库函数的模拟实现
·
一、strlen 和 sizeof
1、strlen
作用:计算有效字符串长度,统计到字符串中的 ‘\0’ 为止之前的个数
局限性:
全靠 ‘\0’ 来终端,如果没有 '\0' 则会越界乱读内存
作用对象只有字符串
2、sizeof
作用:计算数据/数组占用的总内存的大小(字节)
优点:
无规定作用对象,任何类型都能用sizeof来计算总内存大小
永远不会越界
模拟strlen库函数实现:创造一个函数my_strlen,在里面设置判断语句,要是未遇到 '\0' ,就返回 1 + my_strlen(p+1),1的含义是向后查询一位,而(p+1)中1的含义是包括 了'\0',采用递归的方式,只要没有碰到 '\0' 就一直调用它自己,不断累加返回个数


二、strcmp
作用:逐字符比较两个字符串的大小,不比较长度,仅比较字符的ASCII值
返回值:
两个字符串完全相同返回 0
第一个字符串 > 第二个字符串 返回一个正数
第一个字符串 < 第二个字符串 返回一个负数
模拟strcmp库函数的实现:
设置一个函数,传入两个字符串后用一个while循环来判断是否相等,相等则两个字符串的字符均向后移一位进行下一次的比较(倘若第一个字符串为空则直接返回),不相等则跳出循环,直接进入判断语句比较不相等的字符,来返回正数(负数)得到结果

例如:



三、strcat和strncat
1、strcat
作用:拼接字符串,将B字符串接在A字符串的末尾,再自动找A的结尾 \0
缺点:无长度限制,若不检查目标剩余空间,则会越界,安全性差
模拟实现strcat库函数:设置一个函数,传入要拼接的两个字符串,在用ret来保存第一个字符串的地址,先用一个while循环来跳过P1的所有元素,再用一个while循环来将P2的元素插入到P1里面,再用一个指针来接收返回的结果


2、strncat
作用:限定最大凭借字符数的字符追加,属于strcat的安全版
模拟实现strncat库函数:设置一个函数,传入要拼接的两个字符串以及数量,具体代码和上两张图类似,打印返回结果时可以看到当传入数量为3时,仅拼接了wor而不是world,这种拼接更加安全,不会越界


四、strstr
作用:在主串种查找子串第一次出现的位置
局限性:
区分大小写
子串为空,直接返回主串开头
必须完全连续匹配才算成功
只返回第一次匹配的位置
库函数strstr的模拟实现:设置一个函数,将被查找和要查找的字符串传入,若要查找的子串为空串,则直接返回主串。将start存储str1,再用while循环遍历查找,用s1来记录start,s2记录str2,当s1和s2不为0且s1等于s2时就都往后移一位,若未能查找成功则跳出当前循环,主串向后移一位继续查找


五、strcpy和strncpy
1、strcpy
作用:将整个字符串拷贝到目标数组种
规则:
从头开始拷贝,直到遇到 \0 才会停止
会把 \0 一起拷贝过去
没有长度限制
缺点:
不安全,当要拷贝的字符串过长则可能会发生越界,覆盖其他内存
模拟strcpy库函数的实现:设置一个函数传入要拷贝的字符串,因为被拷贝的字符串是不可修改的,所以用const限制一下,在函数循环中,只要ch1不等于 '\0' 就会一直拷贝,拷贝完成后,连同ch2后面的所有元素都会编程ch1中的 '\0'


2、strncpy
作用:最多拷贝 n 个字符,可以控制长度,防止越界
规则:
若源串长度 < n :拷贝全部 + 补 \0 直到满n个
若源串长度 ≥ n:只拷贝前 n 个字符,不会补\0
模拟实现strncpy库函数:设置一个函数来传入拷贝串和被拷贝串以及拷贝字符的数量,再用一个循环,当被拷贝字符串还没被拷贝完和还没超过拷贝字符数量时,进入循环进行拷贝,若拷贝完全部字符串仍未达到拷贝字符的数量,则在拷贝字符串后全补\0直到 i 等于 n 为止

例如将str1中的10个字符拷贝进str2中,结果就是abcdefgh,将str1中的3个字符传入str3中则显示这样的结果是因为以无符号字符打印出来,61对应ASCII码表中的 a,以此类推,78对应 x,最后一个显示00是因为str3中的第五个字符为空,所以显示00
六、memcpy
作用:从前往后拷贝指定字节的内存,遇到\0也不会停
优点:
速度快
逻辑简单
缺点:安全性低,可能会造成数据重叠
模拟实现memcpy函数:设置一个函数,传入void类型的数据和拷贝字节的数量(这样的优点是不分数据类型都能拷贝进指定数据)


七、memmove
作用:与momcpy一样,但拷贝方向是自动判断,可能从前也可能从后
优点:安全性高,不管数据是否重叠都可以用mommove进行拷贝


测试2中源地址str3指向a,目标地址str3+2指向c,目标在源后面且两者重叠,所以从后向前拷贝
拷贝过程:
初始指针位置:
psrc指向str3 + 4(第 5 个字符e)
pdest指向str3 + 2 + 4 = str3 + 6(第 7 个字符g)第 1 步:拷贝
e→g位置 →str3变成a b c d e f e h \0第 2 步:拷贝
d→f位置 →str3变成a b c d e d e h \0第 3 步:拷贝
c→e位置 →str3变成a b c d c d e h \0第 4 步:拷贝
b→d位置 →str3变成a b c b c d e h \0第 5 步:拷贝
a→c位置 →str3变成a b a b c d e h \0
测试3中源地址str4+2指向c,str4指向a,目标在源前面,所以从前向后拷贝
拷贝过程:
初始指针位置:
psrc指向str4 + 2(c)
pdest指向str4(a)第 1 步:拷贝
c→a位置 →str4变成c b c d e f g h \0第 2 步:拷贝
d→b位置 →str4变成c d c d e f g h \0第 3 步:拷贝
e→c位置 →str4变成c d e d e f g h \0第 4 步:拷贝
f→d位置 →str4变成c d e f e f g h \0第 5 步:拷贝
g→e位置 →str4变成c d e f g f g h \0
尾声:感谢大佬阅读本篇文章,博主刚学习到库函数,所以对这些进行了总结,有些不足之处希望各位大佬海涵,还请各位多多指教,共同进步
更多推荐




所有评论(0)