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++知识库 -> memcpy、memmove函数的实现与讲解 -> 正文阅读

[C++知识库]memcpy、memmove函数的实现与讲解

memcpy函数和memmove函数都是内存操作函数,在平时编程的时候,经常需要对一段内存进行操作例如该值或者拷贝。这两个函数对我们很有帮助。

一、memcpy函数概括:

memcpy
Copies characters between buffers.

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

这是对于memcpy函数的介绍。可以看到它的函数参数有三个:

一个是void*的目标地址

一个是const void*的源头地址。这里加const的目的是为了保障安全性

还有一个size_t类型的计数器,这里操作的个数单位是字节

并且返回值是void*的

演示:

可以观察到处于arr1位置开始的20个字节拷贝了从arr+5开始的20个字节所办含的内容。

分析:

其实前面讲的qsort函数的函数参数就是void*的参数,主要是对逐个字节进行操作。

那有了这个想法,我们就可以讲这两个指针后面20个字节的内容逐字节进行拷贝即可。

代码实现:

void my_memcpy(void* dest, void* src, int num)
{
	while (num)
	{
		*((char*)dest) = *((char*)src);
		src = (char*)src + 1;
		dest = (char*)dest + 1;
		num--;
	}
}

这里采用while循环,每操作一个字节就使num减少1。完成模拟。

运行演示:

?可以发现我们自己实现的这个memcpy函数可以模拟实现刚才库函数的效果。

二、memmove函数

memmove
Moves one buffer to another.

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

可以观察到。memmove函数也是void* 的返回值类型,同时也包含三个参数

那已经有memcpy函数了,为什么还会有memmove函数呢?其实,对于上面的代码。是内存不重叠部分进行的拷贝,如果我们需要拷贝的内存相互重叠了,依然采用我们上述的代码就会发生下面情况:

?内存并没有按照我们设想的那样进行复制。

我们理想情况下的:1 2 1 2 3 4 7?8 9 10

实际上是? ? ? ? ? ? ? :1 2 1 2 1 2 7 8 9 10

造成这种结果的原因其实就是我们在arr1[2]位置处拷贝了arr1[0]的数据后

arr1[2]中的结果已经被改为1了,所以下一次访问到它的时候,依然得到的是1

arr1[3]同理。

那怎样能够解决这个问题呢,C语言就设计了memmove函数;

演示:

?不难观察到:memmove函数可以完成这种重叠内存的拷贝。

那它是怎么实现的呢。

分析:

?这是我们的目标地址在源地址的后面的情况。当然还会有目标地址在前面的情况:

?那代码当然就需要分两个部分写了

先判断目标位置和原位置的前后关系,再分两步进行数据的复制:

代码:

void my_memmove(void* dest, void* src, int num)
{
	if (dest > src)
	{
		//后向前
		while (num)
		{
			*((char*)dest + num) = *((char*)src + num);
			num--;
		}
		*((char*)dest) = *((char*)src);
	}
	else
	{
		//从前向后
		while (num)
		{
			*((char*)dest) = *((char*)src);
			dest = (char*)dest + 1;
			src = (char*)src + 1;
			num--;
		}
	}
}

在从后向前进行复制的代码中:

只需要每次都找到对应的位置,循环操作相应的字节数即可

在从前向后进行复制的代码中:

dest和src指向下一个字节的代码要注意不可以直接++。

演示:

?总结:

其实现在vs自带的memcpy函数也不会出现诸如刚才复制错误的情况。但是我们自己写的函数就会错误。这其实是它后来优化的结果。尝试自己模拟实现库函数可以增强对指针和内存的理解。

  C++知识库 最新文章
【C++】友元、嵌套类、异常、RTTI、类型转换
通讯录的思路与实现(C语言)
C++PrimerPlus 第七章 函数-C++的编程模块(
Problem C: 算法9-9~9-12:平衡二叉树的基本
MSVC C++ UTF-8编程
C++进阶 多态原理
简单string类c++实现
我的年度总结
【C语言】以深厚地基筑伟岸高楼-基础篇(六
c语言常见错误合集
上一篇文章      下一篇文章      查看所有文章
加:2022-03-30 18:05:26  更:2022-03-30 18:09:45 
 
开发: 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 2:49:38-

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