目标:掌握基本字符函数的用法,明白熟悉函数功能实现的方法,注意函数使用的规则。
一,strlen函数
strlen函数是一个库函数,头文件为string.h,该函数的功能是求字符串长度,计数时以'\0'为结束标志,函数返回类型为一个无符号整数。
//函数strlen,求字符串长度 // 以"\0"为结束标志 int main() { int ret=strlen("abcdef"); //int ret = strlen("abc\0def");ret为3 printf("%d\n", ret); return 0;//6 //注意, //若无”\0“,则随机值 如char arr[]={'z','c','b'} ,int ret=strlen(arr);//随机值 //其次返回类型为size_t,无符号整形 }
注意函数计算的是字符串,要有以'\0'未结束标志的。否则返回随机值。
注意这里返回值时无符号类型整数,不能当作整形数计算。例:
int main() { if (strlen("abc") - strlen("abcdef") > 0)//这里的计算出的3-6=-3是无符号整数,-3的补码被当作这个数,所以是>0的 { printf(">"); } else { printf("<=");//结果> } return 0; }
这里实现strlen函数有三种方法
1.计数器方法实现strlen
int my_strlen(const char* arr)//这里的返回类型为整数,不会出现上述错误,也可以设计为size_t { //const修饰数组不被改变 int count = 0; assert(arr);//判断是否为空 while (*arr != 0) { count++; } return count; }
采用依次判断是否为零,计数个数。
2.递归实现strlen(某些题目要求不定义变量实现strlen)
int my_strlen(const char* arr) { if (arr) { return 1+ my_strlen(arr+1); } }
若传进指针不为零,则返回1+下一个指针对应的函数。直至1加到空指针,实现计数。
3.指针实现strlen
int my_strlen( char* arr) { char* p = arr; while (arr) { *p++;//指针后移 //p[0]++; } return p - arr;//最后一个减第一个 }
通过用指针相减的方法,得出其中的字符个数。
二,函数strcpy
该函数也是一个以string.h为头文件的库函数,其功能是复制一个字符数组里到另一个字符数组里,覆盖原来的目标函数。这里const修饰源头函数目的不让他发生改变而影响到目的数组。函数返回类型为字符指针。例:
int main() { char arr1[] = "abcdef"; char arr2[20] = { 0 }; strcpy(arr2, arr1);//拷贝字符 printf("%s\n", arr2); //结果为abcdef在arr2里 //char arr[] = "asidjhaoihjduoia"; //char arr2[20] = arr1; arr2=arr1;错误写法 //使用注意事项: char arr3[] = "abc\0def"; strcpy(arr2, arr3);//abc //拷贝的字符串需有“\0”,否则无法正常拷贝 //拷贝时,拷贝过去的字符数组是足够大的,否则破坏数组 //char* p = "abcdefg";这里不能是常量字符串,目标空间必须可以修改才可以使用,如变量,指针 return 0; }
注意这里的strcpy函数在copy一个数组里的字符时,它是以'\0'为结束标志的,原数组字符串里必须有\0,否则无法认定字符串多长。同理\0在哪里,就在哪里结束。这里的数组必须有足够大的空间足够你去拷贝。其次,目标空间必须是可以修改的,否则传参后数组无法修改。
strcpy函数实现方法
//函数实现 char* my_strcpy(char* dest,const char* src)//保护指针src,不引起变化 { char* ret = dest; assert(dest&&src);//断言保证有效性,不为空指针 while (*dest++ = *src++) { ;//覆盖掉原数组 } return ret; }
这里的断言函数确保不是空指针,其头文件为assert.h,否则会报错。
三,strcat函数
该函数为字符追加函数,给一个字符数组后追加另一个字符数组,参数为字符数组的指针,函数类型为char*类型。例:
int main() { char arr1[20] = "hello "; char arr2[] = "world"; strcat(arr1, arr2); printf("%s\n", arr1); return 0; //结果hello world 中间有个空格,空格后面\0,从\0后面追加 char arr1[20] = "hello\0xxxxxxx "; char arr2[] = "world"; strcat(arr1, arr2); printf("%s\n", arr1); return 0; //结果helloworld.原数组与目标数组都需要\0.且目标空间也许需要足够大 }
注意这里的追加函数strcat要求两个字符数组必须有”\0“,函数是以\0为标志,读入一个字符数组,找到\0后修改追加另一个数组,并判段另一个数组\0的结束标志而停止追加。
strcat函数实现方法
//函数实现 char* my_strcat(char* dest, const char* src)//const修饰源头数据不需要改变,不能通过src改变dest的内容 { assert(dest && src); char* p = dest; //找目标空间中的\0 while (*dest != '\0') { dest++; } while (*dest++ = *src++) { ; } return p; }
四,strcmp比较字符
strcmp为一个字符比较函数,参数为两个字符数组指针,返回类型为整形。比较两个字符数组里的字符,一一对应比较若。第一个大于对应的字符,则返回一个大于0的数,否则返回一个小0的值,相等为0.对应字符比较,从第一个不能匹配的字符,就返回,比的是ASCII码值的大小。例:
int main() { char arr1[] = "abcdef"; char arr2 [] = "bbq"; int ret = strcmp(arr1, arr2); printf("%d\n", ret); }
这里的函数与上一个同需要注意两个字符数组”\0“的存在,并且两个字符数组足够大。
strcmp函数实现
//函数实现 int my_strcmp(const char* dest, const char* src) { assert(dest && src); while (*dest == *src) { if (*dest == *src) return 0; dest++; src++; } if (*dest > *src) { return 1; }else { return -1; } }
这里直接用1,-1,0与0判断是否相同。
三个函数的共同点
以上三个函数都是需要长度不受限制的函数,是不安全的函数。不关心长度,即使空间不够,也会强制扩充并实现其功能。例:
int main() { char arr1[]="abcdefg"; char arr2[5]={0}; strcpy(arr1,arr2); printf("%s\n",arr2); //这里的arr2明显装不下arr1,但是这个函数太过野蛮,强制扩充空间用来装 }
这里还有一个函数strncpy,可以自己copy自己,给自己拷贝一个自己
strncpy(arr2, arr1, 3);可以限制个数,比如拷贝三个 ,该函数也会强制扩充,不安全,不够拿0凑。
strncat(arr2,arr1,3).同样多个功能,限制追加的个数,但也可以扩充所追加的个数。
strncmp(arr2,arr1,3),限制比较的个数,但也可以扩充至所比较的个数
函数_s也是类似这种参数形式
这样的函数多加了一个整型参数用来限制其读入字符串的长度。
五,函数strstr
该函数作用用来寻找相同的字符串,若找不到返回空指针,若找到或者多个,返回第一个的地址。例:
int main() { char arr1[] = "abcdefg"; char arr2[]= "bcd"; char* p = strstr(arr1, arr2); if (p == NULL) { printf("找不到"); } else { printf("%s\n", p); } return 0; }
//类似的函数还有strchr strrchr,返回的第一个与最后一个
函数实现
char* my_strstr(const char* str1, const char* str2) { char* s1 = NULL; char* s2 = NULL; char* cp = (char*)str1; s1 = cp; s2 = (char*)str2; while (*cp) { s1 = cp; s2 = (char*)str2; while (*s1 == *s2&&*s1&&s2) { s1++; s2++; } cp++; } return NULL; }
以上是今天所学,加油吧!