一:strlen的使用及模拟使用
strlen函数是计算字符串的长度的,返回的是字符串中’\0’之前的字符个数,单位是字节。
#include <stdio.h> #include <string.h> int main() { char arr[] = "abcdefg"; int len = strlen(arr);//strlen计算的是'\0'之前的字符个数,即a b c d e f g,共七个字符 printf("%d ", len); return 0; }
如果字符中没有’\0’,得到的就会是随机值。
strlen的模拟实现
1:使用计数器实现
思路:使用指针遍历字符串中的内容,指针首先指向字符串首字符的地址,字符串中的字符跳过一个,计数器+1,直到指针指向’\0’的地址。
#include <stdio.h> #include <assert.h> int my_strlen(const char* arr)//原字符串中的内容不需要改 { assert(arr != NULL);//断言 int count = 0;//计数器 while (*arr)//arr中的元素不为'\0',进入循环 { arr++;//跳到下一个元素 count++;//计数器+1 } return count; } int main() { char arr[] = "abcdefg"; int ret=my_strlen(arr); printf("%d ", ret); return 0; }
2:使用指针-指针实现
定义一个指针使其指向字符串首字符的地址,然后使用另一个指针遍历字符串,使这个指针指向’\0’的地址,然后这两个指针相减,得到字符串的长度。
#include <stdio.h> #include <assert.h> int my_strlen( const char* arr) { assert(arr != NULL); char* start = arr;//start指向字符串arr的地址,也就是首字符的地址 while (*arr)//arr中的字符为'\0',停止循环,并且arr指向'\0'的地址 { arr++; } return arr - start;//得到字符串的长度 } int main() { char arr[] = "abcdefg"; int ret = my_strlen(arr); printf("%d ", ret); return 0; }
3:使用递归
//my_strlen("abcdef") //1+my_strlen("bcdef") //1+1+my_strlen("cdef") //1+1+1+my_strlen("def") //1+1+1+1+my_strlen("ef") //1+1+1+1+1+my_strlen("f") //1+1+1+1+1+1+my_strlen("") //1+1+1+1+1+1+0 = 6
#include <stdio.h> #include <assert.h> int my_strlen(const char* arr) { assert(arr != NULL); if (*arr=='\0') { return 0; } return 1 + my_strlen(arr + 1);//递归 } int main() { char arr[] = "abcdef"; int ret=my_strlen(arr); printf("%d ", ret); return 0; }
二:strcpy的使用及其模拟实现
strcpy的使用
strcpy
函数的功能:拷贝字符串
注意事项:
- 源字符串中必须包含\0,同时\0也会被拷贝到目标空间
- 程序员自己要保证目标空间要足够大,能放得下拷贝来的数据
- 保证目标空间必须可以修改
#include <stdio.h> int main() { char a1[] = "abcdef"; char a2[10] = "xx"; strcpy(a2, a1);//将a1字符串中的内容拷贝到a2中去包括'\0' printf("%s\n", a2); return 0; }
二:strcpy的模拟实现
思路:将a1中的内容一一拷贝到a2中,包括’\0’,
方法一:
#include <stdio.h> #include <assert.h> void my_strcpy(char* a2, const char* a1)//a1中的内容并不希望被更改 { assert(a2 && a1);//断言 while (*a1!='\0')//*a1='\0'结束循环 { *a2 = *a1;//将a1中的内容拷贝到a2中 a2++; a1++; } *a2 = *a1;//将a1中的'\0'拷贝到a2中 } int main() { char a1[] = "abcdef"; char a2[20] = { 0 }; my_strcpy(a2, a1); printf("%s\n", a2); return 0; }
方法二:
#include <stdio.h> void my_strcpy( char* a2,const char* a1) { while (*a2 = *a1)//a1中的字符一一拷贝到a2中去,也把'\0'拷贝到a2中去了,只不过这时循环结束 { a2++;//遍历a2 a1++;//遍历a1 } } int main() { char a1[] = "abcd"; char a2[10] = { 0 }; my_strcpy(a2, a1); printf("%s\n", a2); return 0; }
方法三:返回a2首字符的地址
#include <stdio.h> #include <assert.h> char* my_strcpy(char* a2,const char* a1) { char* start = a2; assert(a2 && a1); while (*a2++ = *a1++) { ; } return start; } int main() { char a1[] = "abcdef"; char a2[10] = { 0 }; printf("%s\n", my_strcpy(a2, a1));//返回a2的地址,便于链式访问 return 0; }
三:strcat的使用及模拟实现
strcat的使用
strcat - 字符串追加:
- 目标空间中得有\0(从哪里开始追加),源头字符串中得有\0(追加到什么时候结束)
- 目标空间要足够大,目标要可以修改
#include <stdio.h> int main() { char a1[20] = "hello "; char a2[20] = "world "; strcat(a1,a2);//将a2字符串的内容追加到a1中 printf("%s\n", a1);//打印新的a1 return 0; }
strcat的模拟实现
假设将a2中的内容追加到a1中:
strcat是从a1中’\0’的位置开始追加,并将a2首字符的地址传给a1,以后将a2中的字符一一追加给a1(包括a2中的’\0’)
#include <stdio.h> #include <assert.h> void my_strcat(char* a1, const char* a2) { assert(a1 && a2); while (*a1 != '\0') { a1++; }//此时a1='\0' while (*a2 != '\0') { *a1++ = *a2++;//第一次循环将a1中的'\0'换成a2字符串中的首字符 } *a1 = *a2;//将a2中的'\0'追加到a1中 } int main() { char a1[20] = "hello "; char a2[20] = "world"; my_strcat(a1, a2); printf("%s\n", a1); return 0; }
方法二:链式访问
#include <stdio.h> #include <assert.h> char* my_strcat(char* a1, const char* a2) { char* start = a1;//创建一个新的指针,便于储存a1首字符的地址 assert(a1 && a2); while (*a1 != '\0') { a1++; } while (*a2 != '\0') { *a1++ = *a2++; } return start;//返回a1首字符的地址,便于链式访问 } int main() { char a1[20] = "hello "; char a2[20] = "world!!"; printf("%s\n", my_strcat(a1, a2));//链式访问 return 0; }
#四:strcmp的使用及模拟实现
strcmp的使用
假设比较a1和a2字符串的大小
strcmp根据ASCII值从a1,a2第一个字符开始往后依次比较字符的大小,实现了字符串的大小比较 .
如果a1>a2,返回一个大于0的数;
如果a1=a2,返回一个等于0的数;
如果a1<a2,返回一个小于0的数;
#include <stdio.h> int main() { char a1[] = "abcdef"; char a2[] = "axcb"; int ret=strcmp(a1, a2); printf("%d ", ret); return 0; }
#include <stdio.h> int main() { char a1[] = "abcdef"; char a2[] = "aaxcb"; int ret = strcmp(a1, a2); if (ret > 0) printf(">\n"); else if (ret == 0) printf("=\n"); else printf("<\n"); return 0; }
strcmp的模拟实现
方法一:
#include <stdio.h> int my_strcmp(char* a1, char* a2) { while (*a1 == *a2 )//当*a1=*a2时,往后遍历 { if (*a1 == '\0')//此时*a1=*a2='\0'.a1=a2,返回0; return 0;// a1++; a2++; } if (*a1 > *a2)//当*a1!=*a2时,退出上面循环,进行判断 return 1; else return -1; } int main() { char a1[] = "abcdefgh"; char a2[] = "abcdefg"; int ret = my_strcmp(a1, a2); printf("%d ", ret); return 0; }
方法二:
#include <stdio.h> #include <assert.h> int my_strcmp(const char* a1,const char* a2) { assert(a1 && a2); while (*a1 == *a2 ) { if (*a1 == '\0') return 0; a1++; a2++; } return *a1 - *a2; } int main() { char a1[] = "abcdefg"; char a2[] = "abcdefg"; int ret=my_strcmp(a1, a2); printf("%d ", ret); return 0; }
方法三:
当*a1=a2='\0’时,直接退出循环,将a1-*a2=0返回
include <stdio.h> int my_strcmp(char* a1, char* a2) { while (*a1 == *a2&&*a1!='\0') { a1++; a2++; } return *a1 - *a2; } int main() { char a1[] = "abcdef"; char a2[] = "abcdef"; int ret = my_strcmp(a1, a2); printf("%d ", ret); return 0; }