本文共 3125 字,大约阅读时间需要 10 分钟。
int my_strlen(char* dst) { assert(dst); char* ret = dst; int count = 0; while (*ret!='\0') { ++ret; ++count; } return count;}
har* my_strcat(char* dst, const char* src) { assert(dst && src); char* ret = dst; // 因为后边 dst需要++,所以用ret保存原来的位置 while (*dst != '\0') { //先找到 dst 上'\0' 的位置 ++dst; } while (*dst++ = *src++); //当 dst 到 '\0'了,再将 src 传给 dst return ret;}
和strcpy 不同的是 strcpy是拷贝,strcat是追加拷贝。
int my_strcmp(const char* str1,const char* str2) { assert(str1 && str2); unsigned char* s1 = (unsigned char*)str1; unsigned char* s2 = (unsigned char*)str2; while (*s1 && *s2) { if (*s1 > *s2) { return 1; } else if (*s1 < *s2) { return -1; } else { ++s1; ++s2; } } if (*s1 == '\0'&&*s2 == '\0') { return 0; } else if (*s1 == '\0') { return -1; } else { return 1; }}
strcmp 函数居然是根据字符串中字符的 ASCII 码大小来比较字符串大小的,我有一点不解,假如有两个字符串 str1 = “abbb” 和 str1 = “baaa”,用 strcmp 函数的话,结果是 str2 大于 str1,仅仅是因为 str2 的第一个字符 b 的 ASCII 码大于 str1 的 a。我的想法是应该比较总的 ASCII 码的大小。(仅仅是我自己的臆想,还是按照人家的来吧!)
char* my_strstr(const char* src, const char* sub) { assert(src && sub); const char* srci = src; const char* subi = sub; while (*srci != '\0') { while (*srci == *subi && *subi != '\0') { ++srci; ++subi; } if (*subi == '\0') { return src; } else { subi = sub; ++src; srci = src; } }}
void* my_memcpy(void* dst, const void* src, size_t num) { assert(dst && src); char* str_dst = (char*)dst; char* str_src = (char*)src; for (size_t i = 0; i < num; ++i) { str_dst[i] = str_src[i]; // 等价于 *(str_src + i) } return dst;}
memcpy函数和strcpy函数的一个区别在于,memcpy可以拷贝任意类型的数据,而strcpy函数只能拷贝字符串
memmove 函数的实现
memmove 函数有两种实现的方法。
如图要将红色部分的数据拷贝到黑色部分,第一种情况是内存的前重叠,和不重叠,直接从 src 的前往 src 的后拷贝给 dst,不会影响结果。但是如果是内存的后重叠,如下图: 如果还是按照从前往后进行拷贝,把 src 的第一个数据拷给 dst 的第一个数据时,就已经改变了 src 后边的数据,因为 dst 第一个数据所在位置刚好重叠与 src 后边的数据,这样拷贝,已经改变了还没有拷贝给 dst 的数据,后边拷贝的数据并不是我们最初想要的。所以这种内存后重叠,我们就要从后往前进行拷贝,也就是说,先把 src 的最后一个数据拷贝给 dst 的最后一个数据,然后把 src 的倒数第二个数据拷贝给 dst 的倒数第二个数据,以此类推。这样做就不会改变还没有拷贝给 dst 的 src 数据。 以下有两种拷贝方式,第一种是:给前重叠或者不重叠从前往后拷贝,给后重叠或者不重叠从后往前拷贝(从前往后或者从后往前拷贝都不会影响到内存不重叠的拷贝)。 第二种是:给内存前重叠或者不重叠的从前往后拷贝,给内存后重叠的从后往前拷贝。第一种
void* my_memmove(void* dst, const void* src, size_t num) { assert(src && dst); char* str_dst = (char*)dst; char* str_src = (char*)src; if (str_dst < str_src) { //前重叠或者不重叠,从前往后拷贝 for (size_t i = 0; i < num; ++i) { str_dst[i] = str_src[i]; } } else { //后重叠或者是不重叠,从后往前拷贝 for (int i = num-1 ; i >= 0; --i) { str_dst[i] = str_src[i]; } } return dst; }
**第二种**
void* my_memmove(void* dst, const void* src, size_t num) { assert(src && dst); char* str_dst = (char*)dst; char* str_src = (char*)src; if (str_src < str_dst && str_dst= 0; --i) { str_dst[i] = str_src[i]; } } else { //前重叠或者不重叠,从前往后拷贝 for (size_t i = 0; i < num; ++i) { str_dst[i] = str_src[i]; } } return dst;}
值得一提的是,字符串数组可以用这种方式初始化(char str[] = “abcdefg”),但是不可以用这种方式赋值,这里就可以用到字符串函数 strcpy memcpy memmove
转载地址:http://qqwzi.baihongyu.com/