网站建设管理维护责任书app和网站趋势

当前位置: 首页 > news >正文

网站建设管理维护责任书,app和网站趋势,晋江在线网站建设,网站的内容更新​ ​#x1f4dd;个人主页#xff1a;Sherry的成长之路 #x1f3e0;学习社区#xff1a;Sherry的成长之路#xff08;个人社区#xff09; #x1f4d6;专栏链接#xff1a;C语言进阶 #x1f3af;长路漫漫浩浩#xff0c;万事皆有期待 文章目录1.字符串处理函数介…​ ​个人主页Sherry的成长之路 学习社区Sherry的成长之路个人社区 专栏链接C语言进阶 长路漫漫浩浩万事皆有期待 文章目录1.字符串处理函数介绍1.1 strlen 函数1.2 strcpy 函数1.3 strcat 函数1.4 strcmp 函数1.5 strncpy 函数1.6 strncat 函数1.7 strncmp 函数1.8 strstr 函数1.9 strtok 函数1.10 strerror 函数2.内存函数介绍2.1 memcpy 函数2.2 memmove 函数2.3 memcmp 函数3.模拟库函数的实现3.1 模拟实现strlen 函数3.2 模拟实现strcpy 函数3.3 模拟实现strcat 函数3.4 模拟实现strcmp 函数3.5 模拟实现strstr 函数3.6 模拟实现memcpy 函数3.7 模拟实现memmove 函数4.总结1.字符串处理函数介绍 我们在C语言的从程序代码编写中对字符和字符串的处理相当频繁但是C语言本身并没有字符串类型。而字符串通常放在【常量字符串】或者【字符数组】中。其中字符串常量适用于那些对它不做修改的字符串函数。 1.1 strlen 函数 strlen 函数string length的作用是计算返回字符串中结束标识符 ’ \0 ’ 之前出现的的字符个数因此strlen函数所处理的字符串必须是以结束标识符 ’ \0 ’ 结尾的字符串。其·返回值类型为size_t 类型该类型为无符号类型。 strlen 函数的基本使用方式 #includestdio.h #includestring.hint main() {//两中可行的初始化方式char arr1[]Hello!;char arr2[] { H,e,l,l,o,!,\0 };int ret1 strlen(arr1);int ret2 strlen(arr2);printf(The length of arr1 is %d\n, ret1);printf(The length of arr2 is %d\n, ret2);return 0; }我们使用字符型数组将字符串储存起来接着使用 strlen 函数计算字符串 Hello! 中所有字符的数量使用双引号初始化字符串时编译器将会自动在最后添加上结束标识符并可以使用一个整型变量接收 strlen 函数的返回值进行打印。 并且我们还说到strlen 函数的返回类型为无符号数因此 strlen 函数不可以直接用来比较两个字符串的大小。例如 #includestdio.h #includestring.h int main() {const char* str1 abcdef;const char* str2 bbb; if (strlen(str2) - strlen(str1) 0){printf(str2 str1\n);}else{printf(srt1 str2\n);}return 0; }我们可能会认为计算出的结果为 3 - 6 为 -3结果会执行 else 语句。但事实上因为 strlen 函数的返回类型为无符号类型得出的结果也是无符号类型于是原本第一位即符号位上的数字也将被作为数据的一部分因而实际得出的结果为一个非常大的整数执行了 if 语句。 于是如果我们想要使用 strlen 函数来判断字符串的大小可以通过让它的返回值由无符号数变为有符号数即可即强制类型转换来实现 #includestdio.h #includestring.h int main() {const char* str1 abcdef;const char* str2 bbb;if ((int)strlen(str2) - (int)strlen(str1) 0){printf(str2 str1\n);}else{printf(srt1 str2\n);}return 0; } 1.2 strcpy 函数 在之前的学习中strcpy 函数也是我们经常使用的字符串处理函数之一。 strcpy 函数string copy的作用是可以将字符串从源地址复制至目的地址并且它会将源地址内的结束标识符 ’ \0 ’ 一并拷贝过去因此源地址必须以 ’ \0 ’ 结尾且目的地址也将以结束标识符结尾通俗来讲就是用来实现字符串的复制和拷贝。并且因为其作用为拷贝字符串因此目标地址内的空间必须足够大要有足够的空间容纳下源地址内的字符串同时目的地址的空间必须是可变、可修改的。 strcpy 函数的基本使用方式 #includestdio.h #includestring.h int main() {const char arr1[] Hellow!;const char arr2[10] { 0 };printf(Before copy , the char inside arr1 are %s\n, arr1);printf(Before copy , the char inside arr2 are %s\n, arr2);printf(\n);strcpy(arr2, arr1);//strcpy函数使用格式为strcpy(目的地址, 源地址)printf(After copy , the char inside arr1 are %s\n, arr1);printf(After copy , the char inside arr2 are %s\n, arr2);return 0; }我们要特别注意的是 strcpy 函数返回的是目标空间的起始地址该函数设置返回值值类型的目的是为了实现链式访问 1.3 strcat 函数 strcat 函数string catenate的作用是将源地址的字符串追加补充至目的地址处。与字符串拷贝函数相同它在进行补充追加时是从目的地址的结束标识符处 ’ \0 ’ 开始追加的追加至源地址的结束标识符处停止。且它同样要求目标地址内的空间必须足够大要有足够的空间容纳下源地址内的字符串同时目的地址的空间必须是可变、可修改的。 strcat 函数的基本使用方式 #includestdio.h #includestring.h int main() {const char arr1[20] Hello!;const char arr2[20] Welcome!;printf(Before catenate , the char inside arr1 are %s\n, arr1);printf(Before catenate , the char inside arr2 are %s\n, arr2);printf(\n);strcat(arr2, arr1);printf(After catenate , the char inside arr1 are %s\n, arr1);printf(After catenate , the char inside arr2 are %s\n, arr2);return 0; }注意 strcat 函数无法追加自己。原因很好理解我们在定义时就已经固定了字符数组的储存空间了当追加自己时相当于将自己与和与自己相同大小的字符数组即两倍自身大小的数据放入自己的储存空间中可想而知一定是不可行的。 1.4 strcmp 函数 strcmp 函数string compare的作用为按照顺序依次比较两字符串对应位置字符的 ASCII 码值注意不是比较两字符串的长度直到结束标识符 ’ \0 ’ 或对应位置的字符不同。若比较至结束标识符都没有不同则两字符串相等若两字符串对应位置字符有不同对应位置上字符 ASCII 码值小的字符串小于另一个字符串。 我们来看 strcmp 函数的基本使用方式 #includestdio.h #includestring.h int main() {const char arr1[] abcd;const char arr2[] abz;int ret strcmp(arr1, arr2);//若arr1大于arr2则返回大于零的数//若arr1等于arr2则返回等于零的数//若arr1小于arr2则返回小于零的数if (ret 0){printf(arr1 arr2\n);}else if (ret 0){printf(arr1 arr2\n);}else{printf(arr1 arr2\n);}return 0; }定义并初始化两个字符数组接着对两个数组进行比较根据 strcmp 函数的比较结果得到返回值再根据返回值反馈我们想要的字符串比较结果。 注意并不是比较字符串的长短而是比较对应位置字符 ASCII 码值的大小。 1.5 strncpy 函数 strncpy函数string number copy的作用为将指定长度的字符串复制到字符数组中即表示把源地址中字符串开始的前n个字符拷贝到目的地址中。与 strcpy 相同它同样会将源地址内的结束标识符 ’ \0 ’ 一并拷贝过去因此源地址必须以 ’ \0 ’ 结尾且目的地址也将以结束标识符结尾。并且因为其作用为拷贝字符串因此目标地址内的空间必须足够大要有足够的空间容纳下源地址内的字符串同时目的地址的空间必须是可变、可修改的。 strncpy 函数的基本使用方式 #includestdio.h #includestring.h//strncpy函数的使用 int main() {const char arr1[] Hellow!Welcome!;const char arr2[10] { 0 };printf(Before copy , the char inside arr1 are %s\n, arr1);printf(Before copy , the char inside arr2 are %s\n, arr2);strncpy(arr2, arr1, 7);printf(After catenate , the char inside arr1 are %s\n, arr1);printf(After catenate , the char inside arr2 are %s\n, arr2);return 0; }我们看到使用该函数我们成功的将字符数组 arr1 中的前七个字符拷贝到了字符数组 arr2 中。 注意若源字符串的长度小于我们传递过去的参数则拷贝完源字符串之后将会在目标后追加字符 ’ 0 直到拷贝至参数规定个数。 1.6 strncat 函数 strncat 函数string num catenate的作用为从源地址处将指定长度的字符串追加补充到目的地址中与 strcat 函数类似它在进行补充追加时也是从目的地址的结束标识符处 ’ \0 ’ 开始追加的不同的是追加至参数限制的字符数处停止。但它同样要求目标地址内的空间必须足够大要有足够的空间容纳下出家补充的字符串 同时目的地址的空间必须是可变、可修改的。 strncat 函数的基本使用方式 #includestdio.h #includestring.hint main() {const char arr1[] Hellow!Welcome!;const char arr2[20] Welcome!;printf(Before copy , the char inside arr1 are %s\n, arr1);printf(Before copy , the char inside arr2 are %s\n, arr2);strncat(arr2, arr1, 7);printf(After catenate , the char inside arr1 are %s\n, arr1);printf(After catenate , the char inside arr2 are %s\n, arr2);return 0; }我们可以看到首先定义并初始化两个字符数组接着打印追加补充之前它们各自空间内的内容进行确认然后我们使用了 strncat 函数有限制的从数组 arr1 向 arr2 中追加补充了七个字符。 通过限制长度我们就可以实现字符数组对自己的追加补充了。 1.7 strncmp 函数 strncmp 函数string number compare的作用为有限制的按照顺序依次比较两字符串对应位置字符的 ASCII 码值注意不是比较两字符串的长度直到参数限制位数位置上全部比较结束或对应位置的字符不同。若参数限制位数位置上的字符都比较结束且都没有不同则两字符串相等若两字符串对应位置字符有不同对应位置上字符 ASCII 码值小的字符串小于另一个字符串。 strncmp 函数的基本使用方式 #includestdio.h #includestring.h int main() {const char arr1[] abcd;const char arr2[] abz;int ret strncmp(arr1, arr2, 3);//比较前 3 个字符//若arr1大于arr2则返回大于零的数//若arr1等于arr2则返回等于零的数//若arr1小于arr2则返回小于零的数if (ret 0){printf(arr1 arr2\n);}else if (ret 0){printf(arr1 arr2\n);}else{printf(arr1 arr2\n);}return 0; }其作用原理与作用过程与 strncmp 函数十分类似唯一不同便是限制了字符比较的位数 注意该函数的作用也不是比较字符串的长短而是比较对应位置字符 ASCII 码值的大小 1.8 strstr 函数 strstr 函数string string的作用为从一个字符串中寻找其字串通俗来讲就是从一个字符串中寻找另一个字符串。若找到目标字串则返回指向目标字串的指针若没有找到目标字串则返回空指针不返回 strstr 函数的基本使用方式 #includestdio.h #includestring.h int main() {const char arr1[] abcdefg;const char arr2[] cde;char* ret strstr(arr1, arr2);//从ar1中寻找arr2if (ret NULL){printf(找不到该字符串\n);}else{printf(成功找到该字符串%s\n, ret);}return 0; }我们定义并初始化了两个字符数组并使用 strstr 函数进行字串寻找处理并使用字符型指针接收汉函数的返回值最后对接收了返回值的指针 ret 进行判断若为空则确定为没有从数组 arr1 中找到字串 arr2否则便通过返回值使用指针对字串地址内的数据进行访问。 该函数数有返回值支持进行函数的链式访问 1.9 strtok 函数 strtok 函数string token的作用为将字符串分解为一组字符串。该函数有两个数组作为参数它的实际作用便是将其中一个数组为分割数组在另一个数组中寻找这些“分割符”并在分割符处将这个数组内的字符串加上结束标识符 ’ \0 ’ 将其分割成一组多个字符串。若第一个参数不为 NULL 将找到字符数组中的第一个标记并保存它在字符串中的位置若第一个参数为 NULL 将在同一个字符串中被保存的位置开始查找下一个标记 strtok 函数的基本使用方式 #includestdio.h #includestring.h int main() {char arr1[] 1254594572QQ.COM;char arr2[30] { 0 };strcpy(arr2, arr1);const char* arr3 .;printf(账号%s\n, strtok(arr2, arr3));//找到第一个标记停止printf(服务商%s\n, strtok(NULL, arr3));//从保存好的位置开始往后找printf(网址后缀%s\n, strtok(NULL, arr3));//从保存好的位置开始往后找return 0; }1.strtok 函数是会对数组本身进行操作的所以我们为了保护原始数据在定义并初始化好字符数组之后又定义了一个新的数组并将原始数据拷贝过去作为临时拷贝供我们进行操作。 2.接着我们定义并初始化了分割符数组函数将根据分割符数组 arr3 对 临时拷贝 arr2 进行分割。第一次执行函数时之前没有标记于是直接进行操作找到第一个标记并分割打印。 3.此时就已经存在标记了再连续两次找到前一次执行作下的标记按照分割符将数组分割完毕并打印。 我们可以将上面段代码优化为 #includestdio.h #includestring.h int main() {char arr1[] 1254594572QQ.COM;char arr2[30] { 0 };strcpy(arr2, arr1);const char* arr3 .;char* str NULL;for (str strtok(arr2, arr3); str ! NULL; str strtok(NULL, arr3)){printf(%s\n, str);}return 0; }注意:若字符串中不存在更多的标记则返回 NULL 指针。 1.10 strerror 函数 strerror函数string error的作用为返回错误码对应的信息。即根据接收到的错误码错误码 errno 为全局变量返回错误原因的详细信息。 我们来看 strerror 函数的基本使用方式 #includestdio.h #includestring.h int main() {int i 0;for (i 0; i 4; i){printf(错误原因为%s\n, strerror(i));}return 0; }2.内存函数介绍 2.1 memcpy 函数 memcpy函数memory copy的作用为从源内存空间向目的内存空间拷贝限制数量单位是字节的数据。它与 strcpy 函数类似作用均为拷贝数据不同的是 strcpy 仅仅只操作字符串故会在结束标识符 ’ \0 ’ 处停止而 memcpy 函数操作的是内存内存中的数据是相邻的故不会在结束标识符处停止。 memcpy 函数的基本使用方式 #includestdio.h #includestring.h int main() {int arr1[10] { 1,2,3,4,5,6,7,8,9 };int arr2[5] { 0 };printf(Before copy , the char inside arr2 are :);int i 0;for (i 0; i 5; i){printf( %d, arr2[i]);}printf(\n);memcpy(arr2, arr1, 20);printf(After copy , the char inside arr2 are :);for (i 0; i 5; i){printf( %d, arr2[i]);}printf(\n);return 0; }首先创建并初始化了两个整形数组接着打印出数组 arr2 内数据的存放情况。通过内存拷贝函数将数组 arr1 内的前20个字节的数据拷贝给了 arr2数组。整型数组内每个数据元素所占的内存空间为4个字节20个字节即将数组 arr1 中的前五个数据元素拷贝给了数组 arr2。最后再次打印数组 arr2 中的数据验证拷贝结果。 注意:如果源内存空间和目标内存空间有任何的重叠复制的结果都是未定义的。 2.2 memmove 函数 memmove函数memory move的作用为弥补 memcpy 函数的不足主要用于处理内存的重叠部分。即如果源空间和目标空间出现重叠就得使用 memmove 函数来进行处理。 memcpy 函数的基本使用方式 #includestdio.h #includestring.hint main() {int arr[10] { 1,2,3,4,5,6,7,8,9 };printf(Before copy , the char inside arr are :);int i 0;for (i 0; i 5; i){printf( %d, arr[i]);}printf(\n);memmove(arr2, arr, 20);printf(After copy , the char inside arr are :);for (i 0; i 5; i){printf( %d, arr[i]);}printf(\n);return 0; }2.3 memcmp 函数 memcmp 函数memory compare的作用与 strcmp 函数的作用类似不过 memcmp 函数是从内存的角度以字节为单位进行处理故 memcmp 函数同样需要第三个参数进行限制而不会在结束标识符 ’ \0 ’ 处停止比较。 memcmp 函数的基本使用方式 #includestdio.h #includestring.hint main() {int arr1[] { 1,2,3,4,5,6,7,8,9 };int arr2[] { 1,2,3,4,5,9,6,7,8 };int ret memcmp(arr2, arr1, 24);if (ret 0){printf(arr1 arr2\n);}else if (ret 0){printf(arr1 arr2\n);}else{printf(arr1 arr2);}return 0; }3.模拟库函数的实现 3.1 模拟实现strlen 函数 #define _CRT_SECURE_NO_WARNINGS 1 #includestdio.h #includeassert.hsize_t my_strlen(const char* p) {int count 0;assert(p ! NULL);//进行空指针校验防止出现空指针while (p ! \0){count;p;}return count; }int main() {const char arr[] Welcome!;int ret my_strlen(arr);printf(The length of arr is %d\n, ret);return 0; }3.2 模拟实现strcpy 函数 #define _CRT_SECURE_NO_WARNINGS 1 #includestdio.h #includeassert.hchar my_strcpy(char* p2, const char* p1) {assert(p2 ! NULL);assert(p1 ! NULL);//等价于assert(p2 p1);char* ret p2;//将目的地址作为返回值while (*p2 p1){;}//返回目的地址的作用是为了实现链式访问return ret; }int main() {const char arr1[] Welcome!;const char arr2[10] { 0 };printf(Before copy , the char inside arr1 are %s\n, arr1);printf(Before copy , the char inside arr2 are %s\n, arr2);printf(\n);my_strcpy(arr2, arr1);printf(After copy , the char inside arr1 are %s\n, arr1);printf(After copy , the char inside arr2 are %s\n, arr2);return 0; }3.3 模拟实现strcat 函数 #define _CRT_SECURE_NO_WARNINGS 1 #includestdio.h #includeassert.hchar my_strcat(char* p2, char* p1) {assert(p2 p1);char* ret p2;//查找目标空间中的结束标识符找到后停止while (*p2){p2;}//从结束标识符开始追加//追加while (*p2 p1){;}return ret; } int main() {const char arr1[20] Hellow!;const char arr2[20] Welcome!;printf(Before catenate , the char inside arr1 are %s\n, arr1);printf(Before catenate , the char inside arr2 are %s\n, arr2);printf(\n);my_strcat(arr2, arr1);printf(After catenate , the char inside arr1 are %s\n, arr1);printf(After catenate , the char inside arr2 are %s\n, arr2);return 0; }3.4 模拟实现strcmp 函数 #define _CRT_SECURE_NO_WARNINGS 1 #includestdio.h #includeassert.h //模拟实现strcmp函数 int my_strcmp(const char p1, const char* p2) {assert(p1 p2);//找到字符不同的对应位while (*p1 *p2){if (*p1 \0){return 0;}p1;p2;}if (*p1 p2){return 1;}else{return -1;} }int main() {const char arr1[] abcd;const char arr2[] abz;int ret my_strcmp(arr1, arr2);//若arr1大于arr2则返回大于零的数//若arr1等于arr2则返回等于零的数//若arr1小于arr2则返回小于零的数if (ret 1){printf(arr1 arr2\n);}else if (ret 0){printf(arr1 arr2\n);}else{printf(arr1 arr2\n);}return 0; }3.5 模拟实现strstr 函数 #define _CRT_SECURE_NO_WARNINGS 1 #includestdio.h #includeassert.hchar my_strstr(char* p1, char* p2) {assert(p1 p2); char* pp1 p1;char* pp2 p2;char* cur p1;while (*cur){pp1 cur;pp2 p2;while (*pp1 *pp2 (*pp1 *pp2)){pp1;pp2;}if (pp2 \0){return cur;}cur;}return NULL; }//模拟strstr函数的实现 int main() {const char arr1[] abcdefg;const char arr2[] cde;char ret my_strstr(arr1, arr2);//从arr1中寻找arr2if (ret NULL){printf(找不到该字符串\n);}else{printf(成功找到该字符串%s\n, ret);}return 0; } 3.6 模拟实现memcpy 函数 #define _CRT_SECURE_NO_WARNINGS 1 #includestdio.h #includeassert.hvoid* my_memcpy(void* p2, const void* p1, size_t count) {assert(p2 p1);void* ret p2; while (count–){(char)p2 (char)p1;p2 (char)p2 1;p1 (char)p1 1;}return ret; }int main() {int arr1[10] { 1,2,3,4,5,6,7,8,9 };int arr2[5] { 0 };printf(Before copy , the char inside arr2 are :);int i 0;for (i 0; i 5; i){printf( %d, arr2[i]);}printf(\n);my_memcpy(arr2, arr1, 20);printf(After copy , the char inside arr2 are :);for (i 0; i 5; i){printf( %d, arr2[i]);}printf(\n);return 0; }3.7 模拟实现memmove 函数 #define _CRT_SECURE_NO_WARNINGS 1 #includestdio.h #includeassert.hvoid* my_memmove(void* p2, const void* p1, size_t count) {assert(p2 p1);void* ret p2;if (p2 p1){while (count–){(char)p2 (char)p1;p2 (char)p2 1;p1 (char)p1 1;}}else{while (count–){((char)p2 count) ((char)p1 count);}}return ret; }int main() {int arr[10] { 1,2,3,4,5,6,7,8,9 };printf(Before copy , the char inside arr are :);int i 0;for (i 0; i 5; i){printf( %d, arr[i]);}printf(\n);my_memmove(arr 2, arr, 20);printf(After copy , the char inside arr are :);for (i 0; i 5; i){printf( %d, arr[i]);}printf(\n);return 0; } 4.总结 今天我们对字符串函数与内存函数的相关知识又有了新的了解,学习了10个常用字符串操作函数以及3个常用内存函数的相关知识完成了其中部分库函数的自定义模拟实现希望我的文章和讲解能对大家的学习提供一些帮助。 当然本文仍有许多不足之处欢迎各位小伙伴们随时私信交流、批评指正我们下期见~