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

正能量网站大全金昌网站建设

正能量网站大全,金昌网站建设,网站开发免责合同,西安摩高网站建设大家好&#xff0c;很高兴又和大家见面了&#xff01;&#xff01;&#xff01; 在C语言标准库中&#xff0c;有一些直接对内存进行操作的函数&#xff0c;我们将其称之为内存函数&#xff0c;这些函数位于头文件<string.h>&#xff0c;在网站https://cplusplus.com/ref…

大家好,很高兴又和大家见面了!!!

在C语言标准库中,有一些直接对内存进行操作的函数,我们将其称之为内存函数,这些函数位于头文件<string.h>,在网站https://cplusplus.com/reference/cstring/https://cplusplus.com/https://cplusplus.com/reference/cstring/中我们可以看到这些函数:(ps:这个链接是C语言官网,大家可以打开看一下,十分的详细,包括函数原型等等)

一·必备头文件

所有内存操作函数都声明在<string.h>头文件中,使用前请确保包含:

#include <string.h>

二·五大内存操作函数详解 

1. memcpy - 内存复制专家

1.1函数原型

void* memcpy(void* dest, const void* src, size_t n);

1.2功能:将src指向的地址开始的n个字节,原样复制到dest指向的地址。

  • 函数有三个参数:第一个参数为拷贝的目的地地址,第二个参数为拷贝的源对象的地址,第三个参数为拷贝的大小,单位为字节。
  • 在拷贝的过程中,函数不会受终止符的影响,只会根据字节数量n来进行拷贝;
  • 在拷贝前需要注意,目的地的空间大小和源对象的空间大小都应该至少是n个字节,并且拷贝的目标空间与源空间不能有重叠。

这里提出一个问题,如下:

碰到如下的代码,如何将arr1中的代码拷贝的arr2中?

#include <stdio.h>
#include <string.h>
int main()
{int arr1[] = { 1,2,3,4,5,6 };int arr2[10] = { 0 };}

1.3 可以考虑运用下标的方法来进行拷贝,如下:

先将arr1中的值赋给arr2,在进行打印。

#include <stdio.h>
#include <string.h>
int main()
{int arr1[] = { 1,2,3,4,5,6 };//             0 1 2 3 4 5int arr2[10] = { 0 };for (int i = 0; i < sizeof(arr1) / sizeof(arr1[0]); i++){arr2[i] = arr1[i];}for (int i = 0;i < 6;i++){printf("%d ", arr2[i]);}return 0;}

 

1.4 strcpy函数

这时可能就有同学想到strcpy函数来进行拷贝了,nonononono!!!!

strcpy函数是字符函数,只能用来处理字符,字符串,这里是数组,所以不可以的。

 1.5memcpy函数

#include <stdio.h>
#include <string.h>
int main()
{int arr1[] = { 1,2,3,4,5,6 };int arr2[10] = { 0 };memcpy(arr2, arr1, 24);for (int i = 0;i < 6;i++){printf("%d ", arr2[i]);}return 0;}

 

 1.6 memcpy的模拟实现

memcpy的函数原型可知,其返回类型为无返回指针型,所以我们直接按照函数的原型来实现memcpy,这里我们将自己实现的memcpy命名为my_memcpy。

void* my_memcpy(void* dest, const void* src, size_t num) 
{while (num--) 
{*(char*)dest = *(char*)src;  //进行拷贝//移动指针dest = (char*)dest + 1;src = (char*)src + 1;
}
}

这里大家是否觉得自定义函数已经完成了呢?是否有疑问呢?

比如 dest = (char*)dest + 1; 为什莫不写成++的形式?

为什莫要强制转化成char*的形式?

如果有这样疑问的朋友,那你就忘记指针中的一个重要知识点了,void*类型的指针不能进行+-整数的运算。因此我们如果要一个字节一个字节的移动地址,那此时就需要将void*的指针强转成char*的指针之后再对其进行+-整数的操作。

那这个函数完成了嘛,实践出结果! 请看!!

尽管运行结果的正确的,但这个是因为我使用的是VS2020版本,强行的运行的结果,所以这个函数还是不完整的,根据提示我们短缺一个返回值(对于void类型的函数而言,它和void类型还是有区别的,void函数不需要返回值,但是void类型的函数是需要返回值的。) 

那返回值是什么呢?

memcpy函数介绍中我们不难发现,在memcpy中,函数的返回值是目标空间地址,所以在我们模拟实现的my_memcpy函数中同样可以将目标空间地址返回。为了确保返回的是目标空间的其实地址,我们可以在开始拷贝前,先将目标空间的起始地址记录下来,最后在拷贝结束后将起始地址返回给函数。修改后的如下

#include <stdio.h>
#include <string.h>
#include <assert.h>
void* my_memcpy(void* dest, const void* src, size_t num)
{assert(dest && src);void* ret = dest;while (num--){*(char*)dest = *(char*)src;  //进行拷贝//移动指针dest = (char*)dest + 1;src = (char*)src + 1;}return ret;
}

 

1.7 my_memcpy与memcpy的区别

memcpy函数中,C语言规定它是无法对函数重叠部分进行拷贝的,在我们实现的my_memcpy中可以很好的印证这一点,当有空间重叠的情况存在时,my_memcpy在拷贝时输出的结果会出错,但是在我们在VS中测试memcpy对空间重叠的拷贝时,却能正常拷贝,这说明VS的功能强大。但是在其他的编译器中不一定可以实现了。

如下:

#include <stdio.h>
#include <string.h>
#include <assert.h>
void* my_memcpy(void* dest, void* src, size_t n)
{assert(dest && src);void* ret = dest;while (n--){*(char*)dest = *(char*)src;dest = (char*)dest + 1;src = (char*)src + 1;}return ret;
}
int main()
{int arr[] = { 1,2,3,4,5,6,7,8,9,10 };//     目标:  1 2 1 2 3 4 5 8 9 10// 这里想将12345拷贝到34567my_memcpy(arr + 2, arr, 20);for (int i = 0;i < 10;i++){printf("%d ", arr[i]);}return 0;
}

 

 

所以  memcpy只负责拷贝空间无重叠的情况。 

当空间出现重叠时的拷贝则需要调用我们接下来的函数——memmove 内存移动函数

2.memmove - 安全搬运工

2.1函数原型

void* memmove(void* dest, const void* src, size_t n);

与memcpy的区别是memmove处理的源内存块和目标存快内存可以重叠 。

memmove函数中我们不难发现,它与memcpy的功能是一样的,只不过相较于memcpymemmove可以实现重叠部分的拷贝。函数的使用我就不再过多赘述,与memcpy相同。接下来我们就来重点介绍一下如何实现memmove这个函数。

2.2 memmove的模拟实现

 当来源代码在前时,目标空间在后时,重叠空间为源空间的后侧与目标空间的前侧;

当目标空间在后,源空间在前时,重叠空间则为源空间的前侧与目标空间的后侧。 

 因此我们如果想要在拷贝时不会改变重叠空间的内容,那我们只能先处理重叠空间的内容,再来处理不重叠空间的内容,因此拷贝的方式就有两种情况:

void* my_memmove(void* dest, void* src, size_t num)
{assert(dest && src);void* ret = dest;if (dest > src) {//当源空间在前,重叠空间在后,从后往前拷贝while (num--) {*((char*)dest + num) = *((char*)src + num);}}else{//当源空间在后,重叠空间在前,从前往后拷贝while (num--){*(char*)dest = *(char*)src;dest = (char*)dest + 1;src = (char*)src + 1;}}return ret;
}

这里字节大小是23,大家觉得有问题莫?

没有因为我们强制转化的时候是char*,单位是1个字节,已经高瞻远瞩到现在的情况了。

如果是int*的情况,则

 

总结:

本章节讲解了memcpy和memmove函数,也实现了他们的模拟实现。

  • 内存复制函数——memcpy
  • 内存移动函数——memmove

今天的内容到这里就全部结束啦,在下章为大家讲解剩下的三个函数。

如果大家喜欢博主的内容,可以点赞、收藏加评论支持一下博主,当然也可以将博主的内容转发给你身边需要的朋友。

最后感谢各位朋友的支持,咱们下章再见!!!

 


文章转载自:

http://SgeThgRX.Lsftr.cn
http://Nv71mI4k.Lsftr.cn
http://7bYqy7Er.Lsftr.cn
http://ZcvPmCnK.Lsftr.cn
http://mE5teaUQ.Lsftr.cn
http://iFpAB1A5.Lsftr.cn
http://NTE4Woh8.Lsftr.cn
http://ShCSg2Xu.Lsftr.cn
http://6PSGKqW3.Lsftr.cn
http://dqlHaBpU.Lsftr.cn
http://4TZUzoNm.Lsftr.cn
http://oNxpycy5.Lsftr.cn
http://EKm9OB1z.Lsftr.cn
http://1bsge63b.Lsftr.cn
http://9dvzOcKn.Lsftr.cn
http://oE9YQnwI.Lsftr.cn
http://NuRxEe0Z.Lsftr.cn
http://09MZWY4V.Lsftr.cn
http://nFmvP0qJ.Lsftr.cn
http://Pf2Ry5uy.Lsftr.cn
http://tz3obJsA.Lsftr.cn
http://NUyciDgr.Lsftr.cn
http://HRbnXvwF.Lsftr.cn
http://EpOl89Rq.Lsftr.cn
http://ztp9SOEc.Lsftr.cn
http://QyOE9ldI.Lsftr.cn
http://m45ARhxz.Lsftr.cn
http://P4XaKLEN.Lsftr.cn
http://2QEJz5Gs.Lsftr.cn
http://Jw6hvaNa.Lsftr.cn
http://www.dtcms.com/wzjs/663224.html

相关文章:

  • 福州网站建设公司哪家比较好网站导航怎么设置
  • 双语网站费用企业网站备案要求
  • 套别人的网站模板吗查企业法人信息查询平台
  • 黄岩地区做环评立项在哪个网站salient wordpress
  • 天津手网站开发建e室内设计网官网模型
  • 合肥做网站费用广州市越秀区建设和水务局网站
  • 用自己电脑做网站北京app制作开发公司
  • 课程网站建设简介面包屑导航的网站
  • 一个网站占空间有多少g个人网站 icp 代理
  • 管理手机网站模板网站飘窗 两学一做
  • 设计师配色网站网站建设的销售好做吗
  • 个人网站建设方案书 学生孝感织云网站建设
  • wordpress建站怎么上传网站建站免费
  • 创世网站百度网站下载安装
  • 河南平台网站建设制作市场营销策划公司排名
  • 手机门户网站开发用iis建立网站
  • 北京市朝阳区网站制作公司网站开发找哪个
  • 在线制作书封网站如何认识软件开发模型
  • 企业建立网站的好处株洲网站建设网站建设
  • 网站建设服务方案ppt模板体育用品网站模板
  • ftp网站 免费湖南省交通建设质安监督局网站
  • 做网站威海给网站定位
  • 西安知名网站制作公司2022最新装修效果图
  • 房管局网站建设做网站需要用什么开发软件
  • 集约化网站建设的函西安营销型网站制作价格
  • 宁波网站建设rswl福州seo技巧培训
  • 模板做图 网站东莞做阀门的网站
  • 网站建设保密协议响水做网站的价格
  • 菏泽百度网站建设wordpress 相关文章 插件
  • wordpress网站数据迁移网上购物哪个商城好