手撕字符串函数,包括:
- memcpy
 - memmove
 - strcpy
 - strcat
 - strcmp
 - strstr
 
memcpy
memcpy函数是c和c++使用的内存拷贝函数,
函数原型是:void memcpy(voiddest, const void *src, size_t n);
表示由src指向地址为起始地址的连续n个字节的数据复制到以dest指向地址为起始地址的空间内。与strcpy相比,memcpy并不是遇到’\0’就结束,而是一定会拷贝完n个字节。
注意事项:对于地址重叠的情况,上述函数的行为是未定义的,因此要考虑到此问题
要点:void*类型的指针不能运算,必须强转
void* memcpy(void *dst, const void *src, size_t size)
{
    if (dst == nullptr || src == nullptr)
        return nullptr;
    char *temp_dst = (char*) dst;
    char *temp_src = (char*) src;
    if (temp_dst > temp_src && temp_dst < temp_src+size)
    {
        //内存重叠,自后向前拷贝
        temp_dst = temp_dst+size-1;
        temp_src = temp_src+size-1;
        while (size--)
        {
            *temp_dst-- = *temp_src--;
        }
    }
    else
    {
        //正常拷贝,从前往后
        while (size--)
        {
            *temp_dst++ = *temp_src++;
        }
    }
    return (void*) dst;
}
strcpy
strcpy 只能拷贝字符串,它遇到’\0’就结束拷贝。
char * strcpy(char* dst, const char* src)
{
    if (dst == nullptr || src == nullptr)
        return nullptr;
    char* res = dst;
    while (*dst != '\0')
    {
        *dst++ = *src++;
    }
    return res;
}
strcat
把 src 所指向的字符串追加到 dest 所指向的字符串的结尾。
char* strcat(char *dest,const char *src) {
    //1. 将目的字符串的起始位置先保存,最后要返回它的头指针
    //2. 先找到dest的结束位置,再把src拷⻉到dest中,记得在最后要加上'\0'
    char *ret = dest;
    assert(dest!= nullptr);
    assert(src!= nullptr);
    while(*dest!='\0')
        dest++;
    while(*src!='\0')
        *(dest++)=*(src++);
    *dest='\0';
    return ret;
}
strcmp
把 str1 所指向的字符串和 str2 所指向的字符串进⾏⽐较。
//该函数返回值如下:  | 
strlen
获取字符串长度,通过起始地址和’\0’地址间隔判断
int strlen(const char *str) {
	assert(str != NULL);
	int len = 0;
	while( (*str++) != '\0'){
        len++;
    }
	return len;
}
strfind
在字符串 str1中查找第⼀次出现字符串 str2 的位置,不包含终⽌符 ‘\0’。
char* strstr(const char *str1, const char *str2) {
     char* tmp_s = str1;
     assert(str1 != nullptr);
     assert(str2!= nullptr);
    //若str2为空,则直接返回空
     if(!str2){
         return nullptr;
     }
    //若不为空,则进⾏查询
     while(*tmp_s != '\0') {
     	char* s1 = tmp_s;
     	char* s2 = str2;
     	while(*s1 != '\0' && *s2!='\0' && *s1 == *s2){
            s1++;
            s2++;
        }
        //若s2先结束
        if(*s2 == '\0'){
			return str2;
        }
         //若s1先结束⽽s2还没结束,则返回空
     	if(*s2 != '\0' && *s1== '\0'){
             return nullptr;
        }
    	tmp_s++;
     }
     return nullptr;
}