分享

UC头条:[C语言进阶]最常用的库函数大全——从入门到精通 下

 cnzrp 2023-06-21 发布于山西

二.内存函数

上面我们介绍了处理字符串的函数,但是对于其他类型,我们该如何处理呢?通过下面的内存函数的介绍,相信你会有所感悟!

1.内存拷贝函数

a.memcpy

函数原型:

点击加载图片

注意事项:

这里的destination指向要在其中赋值内容的目标数组,source指向要复制的数据源,num是要复制的字节数,注意这里前两个指针的的类型还有函数返回值都是void*,这是因为,memcpy这个函数是内存拷贝函数,它有可能拷贝整型,浮点型,结构体等等各种类型的数据……虽然返回类型是void*,但他也是必不可少的,void*也表示一个地址,用户可以把它强制转换成自己需要的类型去使用。

点击加载图片

点击加载图片

函数的模拟实现:

void*my_memcpy(void*dest,constvoid*src,size_tnum){void*ret=dest;assert(dest&&src);//前->后while(num--){*(char*)dest=*(char*)src;dest=(char*)dest+1;src=(char*)src+1;}returnret;}

注意:这里对于(char*)dest不能++或--,因为虽然强制转化类型,但是他的类型实质是没有改变的。

然而,这个函数存在缺陷,就是当对于自己拷贝并且有重叠部分时,会出现bug

如果我们只在一个字符串里操作就会出现问题。例如我想把arr1里的1,2,3,4,5拷贝到3,4,5,6,7上就,理论上arr1[]应该变为1,2,1,2,3,4,5,8,9。

但是实际上:

点击加载图片

为了修改这个bug,大佬们又写出了memmove函数!

b.memmove

函数原型和memcpy一样,作用也是一样的,不同的就是可以拷贝自己,并且重叠不会出bug!

为什么之前的模拟实现会出现这个bug呢?

点击加载图片

原因是:当1拷贝到3上时,原来的3已经被1替换,当2拷贝到4上的时候,原来的4已将被2替换。所以当拷贝arr[2]到arr[4]上的时候,原本arr[2]里面存放的3已将被1替换了,同理,所以才得出了不符合我们预期的结果。那如何解决这个问题呢?先来分析这个问题产生的原因,这是因为源空间与目标空间之间有重叠,这里的arr[2]、arr[3]、arr[4]既是源空间也是目标空间,当拷贝1和2的时候把源空间中开没有拷贝的3和4就给覆盖了,此时源空间arr[2]和arr[3]里面存的就不再是3和4了,而是1和2,所以此时拷贝arr[2]和arr[3]里面的数据,其实拷贝的就是1和2。为了解决这个问题,我们可以从后往前拷贝,此时就不会出现这样的问题

但是,我们从后往前拷贝就可以解决这个问题吗?答案是当然不是,比如:

点击加载图片

所以我们需要分类讨论:

点击加载图片

模拟实现:

void*my_memmove(void*dest,constvoid*src,size_tnum){void*ret=dest;assert(dest&&src);if(dest后while(num--){*(char*)dest=*(char*)src;dest=(char*)dest+1;src=(char*)src+1;}}else{//后->前while(num--){*((char*)dest+num)=*((char*)src+num);}}returnret;}

2.内存填充函数——memset

点击加载图片

函数作用:

内存设置

注意事项:

以字节为单位来设置内存中的数据,把从ptr开始往后的num个字节设置成value

形参value也可以是字符,字符其实也是整型,因为字符在内存中存的是其ASCII

value如果是整数的话,需要注意它的取值范围,因为一个字节最大可以存储255,超过255就会发生截断

由于这个函数是一个字节一个字节的改变,所以有些初始化是不成立的,比如对于整形数组初始化为1是不可能实现的,因为每个字节都变成01,一个整形事实上是一个很大的数字。所以对于整形数组初始化,一般都是初始化为0或-1.当然对于字符,不必担心,他本身也是一个字符一个字符改变的!

点击加载图片

3.内存比较函数——memcmp

函数原型:

点击加载图片

注意事项:

比较从ptr1和ptr2指针开始的num个字节

两个内存块中不匹配的第一个字节在ptr1中的值低于ptr2中的值返回一个小于零的数子,相等返回零,两个内存块中不匹配的第一个字节在ptr1中的值大于在ptr2中的值返回一个大于零的数子

总结:

本文通过函数使用的介绍来初步学习,函数的模拟实现来深刻理解了库函数的使用。辛苦各位小伙伴们动动小手,三连走一波最后,本文仍有许多不足之处,欢迎各位认真读完文章的小伙伴们随时私信交流、批评指正!

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多