IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> C++知识库 -> C语言中memmove函数和memcpy函数区别、应用和模拟实现 -> 正文阅读

[C++知识库]C语言中memmove函数和memcpy函数区别、应用和模拟实现

memcpy函数的含义、用法和模拟实现:
首先,memcpy函数是用于复制拷贝一个字符串或者一串数字等等不确定的函数:

从一个memcpy函数编写作者角度来看,?由于传入的地址类型是未知的,不清楚到底是用于拷贝字符串还是数字,因此不知道是复制1个字节还是4个字节还是多少个字节,所以用无定形指针void*接收地址,之后便于强制类型转换来进行拷贝,第一个指针dest代表目标地址,也就是需要拷贝到该地址处,sorc代表需要被拷贝的起始地址,由于不需要被改变所以用const来修饰sorc指针,最后一个num是接收需要拷贝的总字节数,一般调用的时候调用sizeof运算符计算大小来传入。

接下来是模拟实现的源代码:

从图中可以看出来我首先将无定形指针转换成char*类型指针然后赋值给字符型指针p记录赋值前的dest首地址,由于dest在后面会向后增加跳转到后面的地址,于是再赋值前先记录dest首地址,便于之后返回一个地址,这样子复制的时候是一个字节一个字节的进行复制,就可以不用理会是什么类型的指针。然后调用循环结构进行num次循环,也就是num个字节的循环,将dest和sorc指针强制类型转换成char*类型再解引用得到该地址下的内容进行赋值,由于dest和sorc指针都是无定形指针,不能直接进行dest++或者sorc++,需要将其强制转换成char*类型的指针进行+1然后跳过这一个字节继续赋值,最后返回dest的首地址,前面提到过了dest会向后增加所以此时的p就对应了dest的首地址用于返回。
所以举个例子来使用memcpy函数:

这里可以看到字符串A对应12345678,而字符串B对应hello world,在my_memcpy函数中,传入第一个元素A,也就是A字符串的首元素地址,再传入B字符串首元素地址,接着调用sizeof运算符来计算需要赋值的字节大小,可以看到我将B字符串的大小传进去了,也就是"hello world\0"(包括了\0)的字节数,也就是12个字节,然后打印字符串A就可以得到"hello world":
memmove函数的含义、用法和模拟实现:
首先memmove函数和memcpy函数有相似之处,他们用法差不多而且几乎一模一样,但是memmove函数功能更加全面,并且可以避免拷贝区域重叠的时候拷贝出现错误,接下来看模拟实现的memmove的源代码:
可以看到memmove函数和memcpy函数传入的都是void*类型,而且传入的元素一模一样,但是实现的源代码形式不一样:

可以看到这里将dest转换成char*记录dest首地址是跟memcpy一样的,然后这里有区别的是分了两个方向进行拷贝,分别是dest地址大于sorc地址其他
为什么要这样做呢?

原因是如果我在同一个数组里面进行拷贝,第一个元素传入的是A数组的首地址,然后第二个元素传入A数组向后加4的地址,然后拷贝长度为6,也就是说第一个元素的第4、5、6元素和第二个元素B的首元素地址和向后两个长度重合了,那这个时候就分两种情况

这个时候A是目标地址,B是需要被拷贝过去的地址,如果这个时候将B拷贝过去A的话如果从B的第一个元素开始向前拷贝就可以实现,
但是如果是A在B的位置,而B在A的位置:

这个时候,B是源地址,即需要被拷贝地址,而A是目标地址,你需要拷贝过去的地址,你再按照前面的那个方法将B从开头向后进行拷贝到A处,你会发现B与A重叠部分会出现问题,在你拷贝B的向后第五个和第六个地址时候,你从A的角度来看此时A的第一个和第二个地址内容存放的是B一开始第一个和第二个地址里面的内容,此时原来B地址的第五第六个地址对应的内容被覆盖了不能被拷贝,所以要用方法二:即从后往前拷贝,即从B的第六、第五、再到第四这样依次倒序拷贝到A的第六、第五、第四...这样子才能避免刚刚的问题。
此时就分为dest地址在sorc前还是后,即回到刚刚的那个问题为什么要区分dest和sorc地址大小。当然了,如果两个地址以及对应拷贝长度没有重叠,那么从后往前或者从前往后都无所谓,都是可以拷贝过去的,因此就只是分了
”dest大于sorc“”其他“这两种情况。
memmove区别和相同处
从上面可以了解到其实memmove函数和memcpy函数其实
大致是一样的,从起源来说,memcpy函数比较于memmove函数先出现,在后来的发展过程中不断完善后出现了memmove然后解决了以上说到的重叠部分的问题,但也具备memcpy的功能,以此可见在我看来memmove更加好用。都是要包含头文件<string.h>
?


?

  C++知识库 最新文章
【C++】友元、嵌套类、异常、RTTI、类型转换
通讯录的思路与实现(C语言)
C++PrimerPlus 第七章 函数-C++的编程模块(
Problem C: 算法9-9~9-12:平衡二叉树的基本
MSVC C++ UTF-8编程
C++进阶 多态原理
简单string类c++实现
我的年度总结
【C语言】以深厚地基筑伟岸高楼-基础篇(六
c语言常见错误合集
上一篇文章      下一篇文章      查看所有文章
加:2022-01-30 18:45:28  更:2022-01-30 18:46:11 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/24 8:59:39-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码