1.strlen

strlen函数的作用是求字符串的长度,传入字符串的首元素地址,返回该字符串的长度。

注意这里返回值的参数为size_t,即无符号整形,所以返回值ret也应该是size_t类型。而且由于对无符号整形进行加减运算会得到无符号整型,所以无法通过比较两个函数返回的strlen值进行长短比较。

//模拟实现strlen函数
size_t my_strlen(const char* arr)
{assert(arr);//断言,保证arr不为空指针size_t ret = 0;//使用变量进行计数while (*arr++)//当*arr=='\0'跳出循环,否则进入循环ret++;//长度+1return ret;
}

2.strcpy

strcpy函数的作用是将源字符串的内容拷贝到目标空间。

注意

1.源字符串必须以\0结尾,否则拷贝会继续向后进行,直到遇到\0。

2.目标字符串必须要有足够的空间

//模拟实现strcpy函数
char* my_strcpy(char* dest, const char* src)
{assert(dest && src);//断言char* ret = dest;//保存目标字符串首元素地址以便返回while (*dest++ = *src++)//进行拷贝;return ret;
}

3.strncpy

strncpy的作用是将源字符串中指定数量的字符拷贝到目标空间中。

但是也有需要注意的地方:

如果源字符串字符不够,会自动用\0补充。比如源字符串为"abc",转移6个字符,则会拷贝a b c \0 \0 \0到目标空间。

4.strcat

strcat函数的作用是追加一个字符串到目标字符串的结尾。传入目标字符串的首元素地址,与源字符串的首元素地址,返回目标字符串的首元素地址。

使用strcat要注意三点

1.源字符串以必须\0结尾以停止追加

2.目标字符串必须有足够空间,所以目标字符串必须指定大小

3.目标可以被修改

//模拟实现strcat函数
char* my_strcat(char* dest, const char* src)
{assert(dest && src);//断言char* ret = dest;//保存目标字符串首元素地址以便返回while (*dest)//从目标空间起始地址向后寻找\0dest++;while (*dest++ = *src++)//进行追加;return ret;
}

可以看到strcat的模拟实现与strcpy的模拟实现过程非常相似,仅仅是增加了寻找目标字符串结尾位置的步骤。

5.strncat

strncat和strcat的作用类似,但是指定了追加字符的数量。

要注意,如果源字符串没有以\0结尾,则会在追加结束后再追加上\0,且最多只追加一个\0。

6.strcmp

strcmp的作用是进行两个字符串的比较,这里比较的不是字符串的长度,而是比较字符的大小。

假设传入的两个数组为strcmp(arr1,arr2)

这里比较大小的规则为,从两个字符串的第一个字符开始,若同一位字符相同,则比较下一位,若不同,当arr1内的元素ASCII码值大于arr2内的元素,那么返回一个大于0的数,当arr2内的元素ASCII码值大于arr1内的元素,则返回一个小于0的数。若直到两个字符串结束两者都没有出现不等的情况,则返回0,表示两个字符串完全相等。

例如 字符串"abcd"与"abc"比较则返回值大于0(因为d的ASCII码值大于abc后的'\0'的ASCII码值)

"abcd"与"abcc"比较返回值大于0(因为d的ASCII码值大于c的ASCII码值)

而"abc"与"abc"比较则返回0

//模拟实现strcmp函数
int my_strcmp(const char* arr1, const char* arr2)
{assert(arr1 && arr2);//断言while (*arr1 == *arr2 && *arr1)//当arr1内元素与arr2内元素相等且不为'\0'进入循环arr1++,arr2++;//指针分别+1,指向下一个元素return *arr1 - *arr2;//返回比较值,当两者相等时arr1 arr2都指向'\0' 相减为数字0
}

7.strncmp

将两个字符串的前n个字符以strcmp的规则进行比较

8.strtok

strtok函数将把第一个遇到的分割符改为\0,返回第一个分割好的字符串的首元素地址,传入空指针NULL则会从第一个分割符的位置向后查找下一个分割符,如果没有可检索的字符串,则返回一个空指针。

例子:被检索的字符串arr1="ab#cd@ef" 以及分割符字符串arr2="#@",要将arr1进行分割,则

第一次使用:strtok(arr1,arr2),返回值为元素a的地址 arr1="ab\0cd@ef"

第二次使用:strtok(NULL,arr2),返回值为元素c的地址 arr1="ab\0cd\0ef"

第三次使用:strtok(NULL,arr2),返回值为元素e的地址 arr1="ab\0cd\0ef"

注意在第三次使用时,虽然没有寻找到分割符,但是strtok仍对e开头的字符串进行了检索,所以并没有返回空指针,而是返回了元素e的地址。

9.strstr

strstr函数的作用是返回字符串中首次出现子串的地址,找不到则返回NULL,并且当字串为空字符串时,返回字符串的首元素地址。

模拟实现的逻辑为,首先判断arr2是否为空字符串,再进行查找。

查找过程为:每次进入循环先判断arr1是否指向\0,若指向\0则说明arr1遍历结束也没有找到字串,退出循环,返回NULL。若没有指向\0则进入循环,对以arr1为首元素的字串进行判断,若没有找到,则arr1指向下一个元素。

对以arr1为首元素的字串进行判断过程如下:初始化str1与str2指针,分别赋值为arr1与arr2,以供当元素相等时向后查找,当查找过程中str1不等str2或者任意一方指向元素为\0时退出循环,判断str2所指向元素是否为\0。若为\0,则说明找到了字串,此时返回arr1。

这里设计str1与str2的原因在于在判断时要对每一个字符为首的子字符串进行判断,若只使用arr1与arr2,当在"abbbcd"中查找"bbc"时,在arr1指向第一个b时,"bbb"并不能与"bbc"匹配,但在下一次判断时arr1直接指向了d,arr2指向了子串里的c,导致无法正常进行第二次判断,结果出错。

//模拟实现strstr函数
char* my_strstr(const char* arr1,const char* arr2)
{assert(arr1 && arr2);//断言if (!*arr2)//如果arr2为空字符串,返回arr1的首元素地址return (char*)arr1;while (*arr1)//arr1不指向\0时进入循环{char* str1 = (char*)arr1;//定义两个指针进行字符串的匹配char* str2 = (char*)arr2;while (*str1 && *str1 == *str2)//当两者不为\0且相等时进入循环{str1++;//指针分别指向下一个元素str2++;}if (!*str2)//若结束循环后str2指向\0则说明找到字串return (char*)arr1;arr1++;//匹配失败时arr1指向下一个字符}return NULL;//找不到则返回NULL
}

10.memcpy

memcpy函数的作用是将源空间的数据以字节为单位拷贝到目标空间。并且返回目标空间的地址。

//模拟实现memcpy函数
void* my_memcpy(void* dest, const void* src, size_t count)
{assert(dest && src);//断言void* ret = dest;//保留目标空间地址以便返回while (count--)//拷贝count个字节的数据{*(char*)dest = *(char*)src;//拷贝dest = (char*)dest + 1;//指针指向下一个字节src = (char*)src + 1;}return ret;
}

11.memmove

memmove和memcpy的区别是当内存放生局部重叠时,memmove保证结果正确,memcpy不保证拷贝结果正确。memmove会检测拷贝的进行方向并且以不会出错的方向进行拷贝。

为什么说memcpy可能发生错误呢?比如将数组{1,2,3,4,5,6,7,8,9,10}内的1 2 3 4拷贝到 3 4 5 6的位置,按逻辑,结果应该是1,2,1,2,3,4,7,8,9,10

但是从左向右拷贝

拷贝一个整形后 第一个整形1拷贝到第三个整形的位置后数组变为{1,2,1,4,5,6,7,8,9,10}

拷贝两个整形后 第二个整形2拷贝到第四个整形的位置后数组变为{1,2,1,2,5,6,7,8,9,10}

拷贝三个整形后 第三个整形1拷贝到第五个整形的位置后数组变为{1,2,1,2,1,6,7,8,9,10}

拷贝四个整形后 第三个整形2拷贝到第六个整形的位置后数组变为{1,2,1,2,1,2,7,8,9,10}

这与我们设想的结果不同,因为我们拷贝的数据将原有位置的数据覆盖,导致无法正常进行拷贝。但是memmove在拷贝前会进行方向判断,以保证拷贝的结果正确。在上面的例子中,从右向左拷贝,则

拷贝一个整形后 数组变为{1,2,3,4,5,4,7,8,9,10}

拷贝两个整形后 数组变为{1,2,3,4,3,4,7,8,9,10}

拷贝三个整形后 数组变为{1,2,3,2,3,4,7,8,9,10}

拷贝四个整形后 数组变为{1,2,1,2,3,4,7,8,9,10}

也就正常完成了我们的拷贝

//模拟实现memmove函数
void* my_memmove(void* dest, const void* src, size_t count)
{assert(dest && src);void* ret = dest;if (dest > src)//判断目标空间与源空间的关系{//从右向左拷贝dest = (char*)dest + count - 1;src = (char*)src + count - 1;while (count--){*(char*)dest = *(char*)src;dest = (char*)dest - 1;src = (char*)src - 1;}}else{//从左向右拷贝while (count--){*(char*)dest = *(char*)src;dest = (char*)dest + 1;src = (char*)src + 1;}}return ret;
}

C语言<string.h>头文件所包含的部分函数的解析相关推荐

  1. C语言 string.h头文件

    C标准要求在使用字符串函数时要包含头文件string.h,在使用字符函数时包含头文件 ctype.h     函数名     函数原型     功能     返回值     包含文件     isdi ...

  2. string类 string.h头文件 cstring头文件区别以及读取一行字符串总结

    以前一直分不清string类  string.h头文件 cstring头文件的去别,今天ce了一发才稍微弄懂了. 首先C语言中只有string.h头文件,string.h包含了一些字符数组和字符串的函 ...

  3. Ler(一) stdlib.h,stdio.h,string.h头文件

    一.定位不同 1.stdlib.h是standard library标准库头文件,定位在通用工具函数. 2.stdio.h是standard input&output标准输入输出头文件,定位在 ...

  4. C语言 define 防止头文件重复包含 - C语言零基础入门教程

    目录 一.头文件重复包含编译器报错 1.简单的理解头文件重复包 2.老流氓的理解头文件重复包 二.通过宏定义解决头文件重复包含 1.通过 #ifndef / #define 解决头文件重复包含 2.通 ...

  5. string.h头文件

    string.h头文件包含了许多用于字符数组的函数.使用以下函数时需要在开头添加string.h头文件. 1.strlen():该函数可以得到字符数组中第一个\0前的字符的个数,其格式为:strlen ...

  6. C语言中的string.h头文件

    C库提供了多个处理字符串的函数,ANSI C把这些函数的原型放在string.h头文件中. string.h头文件中常用的函数有strlen(),strcat(),strcmp(),strncmp,s ...

  7. c语言windows.h头文件详解

    如果c语言库里没有某个头文件 只需要将下好的头文件放入下面的路径即可 windows.h头文件包含的函数及其用法 1.GetAsyncKeyState()()//通过函数来判断按键按下的状态 主要用法 ...

  8. 关于string.h头文件的函数——C语言

    首先要使用string.h函数,首先要编写#include<string.h> 1.strlen函数:此函数可以求得字符串的长度,但所求长度不包括"\0"所占的长度. ...

  9. C/C++关于string.h头文件和string类

    1.C的字符串头文件是<string.h>,在C++里这个文件变成了<cstring>,string前面的c表示这个是c语言的:而C++的字符串头文件是<string&g ...

最新文章

  1. 如何搭建自己的 pip 本地 cache
  2. [原创]Flex 与 Asp.Net 通过 Remoting 方式进行通讯 (三)
  3. 微软与联合国环境规划署联手解决环境问题
  4. 长远锂科:拟发行可转债募资不超32.5亿元
  5. LeetCode20.有效的括号 JavaScript
  6. ajax用get刷新页面元素在IE下无效解决~~
  7. jQuery 实现点击页面其他地方隐藏菜单
  8. 计算机二级考试c语言 上机,计算机等级考试二级C语言上机题[2]
  9. TCP长连接开发相关,调试工具SocketTool与框架GatewayWorker
  10. 高通模式9008模式linux,学会小米9008高通模式_原来刷机如此简单
  11. AGV项目底层总结二
  12. 看完了想点赞的文章!| 数据类好文推荐
  13. Python Appium自动化测试框架 综合实践案例(中)
  14. JAVA 导出Excel 带有多个公式函数
  15. 『HTML5实现人工智能』小游戏《井字棋》发布,据说IQ上200才能赢【算法代码讲解+资源打包下载】...
  16. Excel单元格设置下拉选项
  17. 微信小程序中使用阿里巴巴字体图标
  18. 台式计算机内存可以扩展到多大,64位电脑系统可以支持多大内存【详细介绍】...
  19. 【1024】写给最好的你-程序员
  20. 无为二中2021高考成绩查询,2019无为二中录取分数线(附2019高考成绩喜报)

热门文章

  1. 阿里云计算巢加速企业软件云化,助力企业业务创新
  2. 北京大学肖臻老师《区块链技术与应用》公开课笔记16——ETH账户篇
  3. Docker2 docker commit方法镜像制作
  4. Java基础编程练习50题(转载)
  5. 内部方法调用,事务不起作用的原因及解决办法
  6. 【JAVA-规约】阿里巴巴JAVA开发手册
  7. [C5W2] Sequence Models - Natural Language Processing and Word Embeddings
  8. ssh登录linux
  9. 一篇搞定“什么是个人IP”
  10. TLC2543芯片AD转换例子