memcpy、memcmp、memset、strlen、strcpy等实现

C语言实现

  • 1. void *memcpy(void *destin, void *source, unsigned n)
  • 2. int memcmp(const void *str1, const void *str2, size_t n))
  • 3. void *memset(void *s, int ch, size_t n)
  • 4. size_t strlen(const char *string)
  • 5. char **strcpy(char* dest, const char *src)
  • 6. int strcmp(const char *s1, const char *s2)
  • 7. char *strcat(char *dest, const char *src)

1. void *memcpy(void *destin, void *source, unsigned n)

  • void memmove( void dest, const void* src, size_t count )
  • memcpy 函数的功能是从源内存地址的起始位置开始拷贝若干个字节到目标内存地址中,即从源source中拷贝n个字节到目标destin中
void* user_memcpy(void *dest, const void *source, size_t n)
{
    char *d = NULL;
    const char *s = NULL;

    if (NULL == dest || NULL == source || n < 0)
    {
        return NULL;
    }

    d = (char*)dest;
    s = (const char*)source;

    // 需考虑内存存在覆盖情况 overlap
    // 1. 当源内存首地址大于目的内存首时,从低地址往高地址复制
    // 2. 当源内存首地址小于目的内存首时,从高地址往低地址复制
    // 3. 首地址相同,不做动作

    if (s > d)           //1
    {
        //正常从低地址往高地址复制
        while (n--)
        {
            *d++ = *s++;
        }
    }
    else if (d > s)      //2
    {
        //从高地址往低地址复制
        s += n - 1;
        d += n - 1;

        while (n--)
        {
            *d-- = *s--;
        }
    }
    //    else
    //    {
    //        //do nothing
    //    }
    return dest;
}
  • 上面为按byte拷贝的,在具体的平台上还可以再优化下,达到速度更快
  • memmove功能与memcpy功能差不多

2. int memcmp(const void *str1, const void *str2, size_t n))

  • 对存储区 str1 和存储区 str2 的前 n 个字节进行比较,按byte进行比较
  •   当str1 < str2 时,返回值 <0
      当str1 = str2 时,返回值 =0
      当str1 > str2 时,返回值 >0
    
int user_memcmp(void *str1, const void *str2, size_t n)
{
	assert(str1 != NULL && str2 != NULL && n > 0);

    const char *buf1 = (const char*)str1;
    const char *buf2 = (const char*)str2;

    while (n--) 
    {
        if (*buf1++ != *buf2++)
        {
            return buf1[-1] < buf2[-1] ? -1 : 1;
        }
            
    }
    return 0;
}

3. void *memset(void *s, int ch, size_t n)

  • 将某一块内存中的内容全部设置为指定的值,通常为新申请的内存做初始化工作
  • 以s为起始位置的n个字节的内存区域用整数ch进行填充
  • memset函数是以byte为单位进行赋值的
void* user_memset(void *s, int ch, size_t n)
{
    char* tmp = NULL;

    if (s == NULL || n < 0)
    {
        return NULL;
    }

    tmp = (char*)s;

    while (n--)
    {
        *tmp++ = ch;
    }
    return s;
}

4. size_t strlen(const char *string)

  • 功能是计算字符串的实际长度。从string起始地址往后查找,直到查找到’\0’时停止,如果string里没有’\0’,会继续找下去,直到遇到’\0’停止。返回长度不包括 ‘\0’ 。
size_t user_strlen(const char *src)
{
    size_t len = 0;
    const char* tmp = NULL;
    assert(src);

    tmp = src;
    while (*tmp++ != '\0')
    {
        len++;
    }
    return len;
}

5. char *strcpy(char dest, const char *src)

  • 把从src地址开始且含有NULL结束符的字符串复制到以dest开始的地址空间
  • src 和 dest 所指内存区域不可以重叠且dest必须有足够的空间来容纳src的字符串
char *user_strcpy(char *dest, const char *src)
{
    char* d = NULL;
    const char* s = NULL;

    assert(dest && src);

    d = dest;
    s = src;

    while(*d++ = *s++);

    return dest;
}

6. int strcmp(const char *s1, const char *s2)

  • strcmp函数是string compare(字符串比较)的缩写,用于比较两个字符串并根据比较结果返回整数
  • 若str1=str2,则返回值 =0
  • 若str1
  • 若str1>str2,则返回值 >0
int user_strcmp(const char *s1, const char* s2)
{
    int ret = 0;

    while( !(ret = *(unsigned char*)s1 - *(unsigned char*)s2) && *s1 )
    {
        s1++;
        s2++;
    }

    if(ret < 0)
    {
        return -1;
    }
    else if(ret > 0)
    {
        return 1;
    }
    return 0;
}

7. char *strcat(char *dest, const char *src)

  • 把src所指向的字符串 (包括 ‘\0’ )复制到dest所指向的字符串后面(删除*dest原来末尾的 ‘\0’ )
  • 要保证dest足够长,以容纳被复制进来的src
  • *src中原有的字符不变。返回指向dest的指针
char* user_strcat(char *dest, char *src)
{
    char *d = NULL;
    char *s = NULL;

    assert(dest && src);
    d = dest;
    s = src;

    while(*d)
    {
        d++;
    }

    while(*d++ = *s++);

    return dest;
}

你可能感兴趣的:(C语言,字符串,c语言)