/*------------------------------------------------------------------------------------------------- 面试题之strcpy / strlen / strcat / strcmp的实现; -------------------------------------------------------------------------------------------------*/ #include <assert.h> #include <stdio.h> /*------------------------------------------------------------------------------------------------- 一、字符串拷贝strcpy; 函数strcpy的原型是 char* strcpy(char* des, const char* src); des 和 src 所指内存区域不可以重叠且 des 必须有足够的空间来容纳 src 的字符串; -------------------------------------------------------------------------------------------------*/ char* strcpy(char* des, const char* src) { assert(des && src); char* tempAddr = des; while ('\0' != (*des++ = *src++)) { } return tempAddr; } /*------------------------------------------------------------------------------------------------- // 答案考点; 1. 要知道 strcpy 会拷贝’\0’; 2. 还有要注意:源指针所指的字符串内容是不能修改的,因此应该声明为 const 类型; 3. 要判断源指针和目的指针为空的情况,思维要严谨,这里使用assert; 4. 要用一个临时变量保存目的串的首地址,最后返回这个首地址; 5. 函数返回 char* 的目的是为了支持链式表达式,即strcpy可以作为其他函数的实参; -------------------------------------------------------------------------------------------------*/ /*------------------------------------------------------------------------------------------------- 二、字符串长度strlen; 函数strlen的原型是 size_t strlen(const char *str); 其中 size_t 就是 unsigned int; -------------------------------------------------------------------------------------------------*/ size_t strlen(const char *str) { assert(str); size_t iLen = 0; while ('\0' != *str++) { ++iLen; } return iLen; } /*------------------------------------------------------------------------------------------------- // 答案考点; strlen 与 sizeof 的区别; sizeof是运算符,strlen是库函数; sizeof可以用类型、变量做参数,而strlen只能用 char* 变量做参数,且必须以\0结尾; sizeof是在编译的时候计算类型或变量所占内存的大小,而strlen的结果要在运行的时候才能计算出; 来,用来计算字符串的长度; 数组做sizeof的参数不退化,传递给strlen就退化为指针了; -------------------------------------------------------------------------------------------------*/ /*------------------------------------------------------------------------------------------------- 三、字符串连接strcat; 函数strcat的原型是 char* strcat(char* des, char* src); des 和 src 所指内存区域不可以重叠 且 des 必须有足够的空间来容纳 src 的字符串; -------------------------------------------------------------------------------------------------*/ char* strcat(char* des, char* src) { assert(des && src); char* tempAddr = des; while (*des != '\0') // 移动到字符串末尾; { ++des; } while ('\0' != (*des++ = *src++)) { } return tempAddr; } /*------------------------------------------------------------------------------------------------- // 答案考点; 移动到字符串末尾 后 同strcpy处理; -------------------------------------------------------------------------------------------------*/ /*------------------------------------------------------------------------------------------------- 四、字符串比较strcmp; 函数strcmp的原型是 int strcmp(const char *s1, const char *s2); 若s1 == s2,返回零; 若s1 > s2,返回正数; 若s1 < s2,返回负数; 即:两个字符串自左向右逐个字符相比(按ASCII值大小相比较),直到出现不同的字符或遇\0为止; -------------------------------------------------------------------------------------------------*/ int strcmp(const char *s1, const char *s2) { assert(s1 && s2); while (*s1 == *s2) { if ('\0' == *s1 ) { return 0; } s1++; s2++; } return *s1 - *s2; } /*------------------------------------------------------------------------------------------------- // 答案考点; 移动到字符串末尾 后 同strcpy处理; -------------------------------------------------------------------------------------------------*/ void main() { // strcpy test; { char dest1[5]; char dest2[20]; char src[10] = "abcdef"; int iLen1 = strlen(strcpy(dest1, src)); int iLen2 = strlen(strcpy(dest2, src)); int i = 0; } // strcat test; { char dest1[6] = "12345"; char dest2[20] = "12345"; char src[10] = "abcdef"; int iLen1 = strlen(strcat(dest1, src)); int iLen2 = strlen(strcat(dest2, src)); int i = 0; } // strcmp test; { char str1[10] = "12345"; char str2[20] = "12345"; char str3[20] = "12354"; char str4[20] = "12234"; int iRes1 = strcmp(str1, str2); int iRes2 = strcmp(str1, str3); int iRes3 = strcmp(str1, str4); int iRes4 = strcmp(str3, str4); int i = 0; } // 最后析构dest1出错 越界; } // memcpy 与 memmove 的区别;