strlen、strcmp、strcat、strlen、memmove
#include <cassert> #include <iostream> using namespace std; /* strlen 返回字符串不包含结束符\0的长度 */ int mystrlen(const char *str) {//非递归strlen assert(str);//必须不为空 int len = 0; while (*str++) len++; return len; } int mystrlen1(const char *str) {//递归 stelen if (*str == '\0') return 0; return mystrlen1(str + 1) + 1; } /* strcmp,如果str1大,返回正数,小返回负数,相等返回0 ascii码共128种(0-127),所以可以转为unsigned char(范围-128到127) 且无符号两数相等情况下相减必为0,而有符号相减为0,两数的每一位不一定相等 */ int mystrcmp(const char* str1,const char* str2) { assert(str1 && str2);//允许一个为空 int ret = 0; while (!(ret = *(unsigned char*)str1 - *(unsigned char*)str2) && *str1)//注意*str1放后面,前面肯定计算完毕 {//结束符ascii码是0。相等进入while,不相等则ret存储差值,如果str1短,已经是负值,长则为正值 str1++; str2++; } if (ret > 0) return 1; else if(ret < 0) return 0; else return 0; } /* strcat 返回新dst。将字符串src包括结束符都复制到dst后,注意覆盖dst的\0 不考虑dst不够存放src的情况(会报错,但没法处理,因为dst为指针,不知其空间大小 */ char *mystrcat(char *dst,const char *src) { assert(dst && src);//允许一个为空 char *tmp = dst; while (*tmp) tmp++;//指到dst的结束符处(比strcpy多了这一步 while (*src) *tmp++ = *src++; *tmp = *src;//复制结束符 return dst; } /* strcpy 返回新dst,将字符串src包括结束符全部复制到dst开始处 不考虑dst不够存放src,容易溢出 */ char *mystrcpy(char *dst, const char *src) { assert(dst && src); char *tmp = dst; while (*src) *tmp++ = *src++; *tmp = *src; return dst; } /* memmove size指定复制长度,如果源在前且与目标有重叠,则逆向复制 而memcpy都是正向复制 */ void *mymemmove(void *dst, void *src, size_t size) { if (dst == nullptr || src == nullptr) return nullptr; void *res = dst; char *pdst = (char *)dst; char *psrc = (char *)src; if (pdst >= psrc && pdst <= psrc + size) { for (int i = size - 1; i >= 0; i--) *(pdst + i) = *(psrc + i);//源在前,逆向复制 } else { for (int i = 0; i < size; i++) *(pdst + i) = *(psrc + i);//源在后/不重叠,正向复制 } return dst; } int main() { char str[] = {'1','2','3'}; const char *a = "12"; //cout << mystrlen(a) << endl; //cout << mystrcmp("2222", "22") << endl; char dst[5] = "12"; cout << mystrcat(dst, "34") << endl; cout << mystrcpy(dst, "34") << endl; }