当前位置:   article > 正文

常用字符函数和字符串函数详解_字符串的各种函数

字符串的各种函数

     目录

本章重点

一、strlen函数

二、strcpy函数

三、strcat函数

四、strcmp函数

五、strncat函数

六、strncpy函数

七、strncmp函数

八、strstr函数

九、memcpy函数

十、memmove函数


本章重点

本文重点介绍字符和字符串的库函数得使用和注意事项

深度解析库函数,并实现相关的库函数


一、strlen函数

函数原型

size_t strlen ( const char * str );

函数介绍

  • strlen函数是用于计算字符串长度的
  • 字符串以"\0"作为结束标志,此函数就是计算"\0"之前的字符个数
  • 返回值为 size_t size_t原型为 typedef unsigned int size_t 是无符号整型的重命名,因为strlen函数是计算字符串长度,不可能为负数
  • 参数用const char*  的指针接收,const为不可修改增加了函数的安全性

函数模拟实现

下述展示三种strlen函数的模拟实现,三种不同的思路

方法一:计算头尾指针的距离从而得到字符串的长度

  1. size_t my_strlen(const char* arr)
  2. {
  3. assert(arr != NULL);//断言函数,用于判断函数是否为空
  4. const char* ret = arr;//将字符数组首地址赋值给ret指针变量
  5. while (*ret)//当ret解引用不为\0时循环继续
  6. {
  7. ret++;//指针向后偏移
  8. }
  9. return ret - arr;//计算出指针的偏移量从而得到字符串的长度
  10. }

方法二 :利用一个标记,当数组内容不为\0时标记加一,从而得到字符串长度

  1. size_t my_strlen1(const char* arr)
  2. {
  3. assert(arr != NULL);
  4. int sum = 0;
  5. while (*arr)
  6. {
  7. arr++;
  8. sum++;
  9. }
  10. return sum;
  11. }

方法三: 递归实现,当数组内容不为\0时递归调用

  1. size_t my_strlen2(const char* arr)
  2. {
  3. assert(arr != NULL);
  4. if (*arr)
  5. return 1 + my_strlen2(arr+1);
  6. else
  7. return 0;
  8. }


二、strcpy函数

函数原型

char* strcpy(char * destination, const char * source );

函数介绍

  • strcpy是实现字符串拷贝的函数
  • destination是目标数组,source是用于拷贝的数组,即将source数组中的内容拷贝到destination中
  • source字符串必须以 '\0' 结束。
  • 会将source字符串中的 '\0' 拷贝到目标空间。
  • destination空间必须足够大,以确保能存放source字符串。
  • destination空间必须可变。

函数模拟实现

  1. char* my_strcpy(char* destination, const char* source)
  2. {
  3. assert(destination && source);
  4. char* ret = destination;//用一个字符指针记录des数组的起始地址
  5. while (*destination = *source)//当source内容为\0时循环结束
  6. {
  7. destination++;
  8. source++;
  9. }
  10. return ret;//返回des起始地址
  11. }


三、strcat函数

函数原型

char * strcat ( char * destination, const char * source );

函数介绍

  • strcat是字符串追加函数
  • 将source的内容追加到destination中
  • source字符串必须以 '\0' 结束。
  • destination空间必须有足够的大,能容纳下源字符串的内容。
  • destination空间必须可修改。

函数模拟实现

  1. char* my_strcat(char* arr1, const char* arr2)
  2. {
  3. assert(arr1 && arr2);
  4. char* ret = arr1;//使用一个字符指针记录目标数组的首地址
  5. while (*arr1)//当目标函数内容为\0时,开始追加
  6. {
  7. arr1++;
  8. }
  9. while (*arr1 = *arr2)//开始追加字符串
  10. {
  11. arr1++;
  12. arr2++;
  13. }
  14. return ret;
  15. }

四、strcmp函数

函数原型

int strcmp ( const char * str1, const char * str2 );

函数介绍

  • strcmp函数时比较两个字符串的大小
  • 第一个字符串大于第二个字符串,则返回大于0的数字
  • 第一个字符串等于第二个字符串,则返回0
  • 第一个字符串小于第二个字符串,则返回小于0的数字

函数模拟实现

  1. int my_strcmp(const char* arr1, const char* arr2)
  2. {
  3. assert(arr1 && arr2);
  4. while (*arr1 == *arr2)//通过ascll码值依次比较每个字符的大小
  5. {
  6. //当字符数组内容为\0时还没有比较出大小则表示两字符串相等
  7. if (*arr1 == '\0')
  8. return 0;//相等则返回0
  9. arr1++;
  10. arr2++;
  11. }
  12. return *arr1 - *arr2;//不相同等返回差值
  13. }


五、strncat函数

函数原型

char * strncat ( char * destination, const char * source, size_t num );

函数介绍

  • 只是在原有的strcat的基础上增加了一个size_t num
  • 表示只追加num个字符

函数模拟实现

  1. char* my_strncat(char* arr1, const char* arr2, size_t num)
  2. {
  3. assert(arr1 && arr2);
  4. char* ret = arr1;
  5. while (*arr1)
  6. {
  7. arr1++;
  8. }
  9. while (num--)//只追加num个字符
  10. {
  11. *arr1 = *arr2;
  12. arr1++;
  13. arr2++;
  14. }
  15. return ret;
  16. }

六、strncpy函数

函数原型

char * strncpy ( char * destination, const char * source, size_t num );

函数介绍

  • 在原有strncpy上增加了一个size_t num
  • 表示只复制num个字符

函数模拟实现

  1. char* my_strncpy(char* arr1, const char* arr2, size_t num)
  2. {
  3. assert(arr1 && arr2);
  4. char* ret = arr1;
  5. while (num--)//控制复制的字符数
  6. {
  7. *arr1 = *arr2;
  8. arr1++;
  9. arr2++;
  10. }
  11. return ret;
  12. }

七、strncmp函数

函数原型

int strncmp ( const char * str1, const char * str2, size_t num );

函数介绍

  • 字符串比较函数,只比较num个字符
  • 相较于strcmp只多了一个num

函数模拟实现

  1. int my_strncmp(const char* arr1, const char* arr2 ,size_t num)
  2. {
  3. assert(arr1 && arr2);
  4. while (num--)
  5. {
  6. if (*arr1 == *arr2)//字符相等时指针后移
  7. {
  8. arr1++;
  9. arr2++;
  10. }
  11. else
  12. {
  13. return *arr1 - *arr2;//只要有不相等时就返回两个字符的差
  14. }
  15. }
  16. return 0;//循环结束任然相等返回0
  17. }

八、strstr函数

函数原型

char * strstr ( const char *str1, const char * str2);

函数介绍

  • strstr函数是在str1字符串中查找str2字符串是否为str1的子串

函数模拟实现

  1. char* my_strstr(const char* arr1, const char* arr2)
  2. {
  3. const char* s1 = arr1;//利用s1指针记录被查询数组的地址
  4. const char* s2 = arr2;//s2记录查询数组的地址
  5. const char* p = arr1;//p指针为被查询数组的偏移量
  6. while (*s1)
  7. {
  8. s1 = p;//从arr1第一个字符开始对比,不是字串就偏移一位
  9. s2 = arr2;
  10. while (*s1 == *s2)
  11. {
  12. s1++;
  13. s2++;
  14. }
  15. if (*s2 == '\0')//如果查询的数组为\0了那就证明arr2是arr1的子串
  16. {
  17. return p;
  18. }
  19. p++;
  20. }
  21. return NULL;
  22. }

九、memcpy函数

函数原型

void * memcpy ( void * destination, const void * source, size_t num );

函数介绍

  • 函数memcpy从source的位置开始向后复制num个字节的数据到destination的内存位置。
  • 这个函数在遇到 '\0' 的时候并不会停下来。
  • 如果source和destination有任何的重叠,复制的结果都是未定义的
  • 可以传任意参数,不局限于字符数组
  • 这里的num是字节数,例如传整型数组,一个整型是4字节,10个整型num的值为40

函数模拟实现

  1. void* my_memcpy(void* arr1, const void* arr2,size_t num)
  2. {
  3. void* ret = arr1;
  4. assert(arr1 && arr2);
  5. while (num--)//num为字节数,这样就保证了能够一个字节一个字节的交换
  6. {
  7. *(char*)arr1 = *(char*)arr2;//将传过来的地址强制类型转换为字符型
  8. //一个字节一个字节的复制
  9. arr1 = (char*)arr1 + 1;//强转为char*型这样指针偏移量就为1
  10. arr2 = (char*)arr2 + 1;
  11. }
  12. return ret;
  13. }

十、memmove函数

函数原型

void * memmove ( void * destination, const void * source, size_t num );

函数介绍

  • 和memcpy的差别就是memmove函数处理的源内存块和目标内存块是可以重叠的。
  • 如果源空间和目标空间出现重叠,就得使用memmove函数处理

函数模拟实现

重叠情况一:当source指针在destination指针后面时,直接数字从前向后复制移动即可

 

重叠情况2:当source指针在destination指针前面时,直接数字从后向前复制移动即可

  1. void* my_memmove(void* arr1, const void* arr2, size_t num)
  2. {
  3. void* ret = arr1;
  4. assert(arr1 && arr2);
  5. if (arr1 <= arr2)//当目标函数指针在源函数左边时
  6. {
  7. while (num--)//从左向右复制
  8. {
  9. *(char*)arr1 = *(char*)arr2;
  10. arr1 = (char*)arr1 + 1;
  11. arr2 = (char*)arr2 + 1;
  12. }
  13. }
  14. else//目标函数在源函数右边时
  15. {
  16. while (num--)//从右向左依次复制
  17. {
  18. *((char*)arr1 + num) = *((char*)arr2 + num);
  19. }
  20. }
  21. return ret;
  22. }

 总结

万丈高楼平地起,没有基础就没有后面的高楼,即使这些库函数并没有什么很难的算法,但是也是需要我们去学习的

这里总结了10个常用库函数的使用以及使用的注意事项,同时也给出了这些库函数的模拟实现

这里肯定还是存在问题的,希望看到的诸君不吝赐教!

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/小蓝xlanll/article/detail/71523
推荐阅读
相关标签
  

闽ICP备14008679号