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的模拟

0.回顾

strcpy只是做字符串copy,而memcpy和memmove不必关心任何类型数据

1.memcpy()使用:

  • strncpy(char* dest, const char* src, size_t count); 两者参数很像
    memcpy(void* dest, const void* src, size_t count):把源数据拷贝到dest,大小为count,返回的是目标空间起始地址,即返回无类型的void*
  • const放在*左边表示指针所指向内容,不能通过指针改变。 const对星和内容一起限定,指针指向内容不能改变,是一种保护。
  • 使用示例:
int main()
{
	int arr1[10] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
	int arr2[5] = { 0 };
	memcpy(arr2, arr1, 20);

	return 0;
}

效果:
请添加图片描述
复制的是int类型5个数字,有20个字节,所以如右侧复制了5个

1. 自写memcpy()

void* my_memcpy(void* dest, const void* src, size_t count)
{
	// 断言判断dest和src输入
	assert(dest&&src);
	// 按长度减少不断做
	while (count--)
	{
		assert(dest&&src);
		void* ret = dest;	
		// 1个字节的走,所以先(char*)对dest一个字节地做,然后通过解引用,即外加*拿到内容
		*(char*)dest = *(char*)src;
		// 然后挪动一个字节 但void的dest不能直接++,要一个字节一个字节做,所以用char*,
		dest = (char*)dest + 1;
		src = (char*)src + 1;
	}
	return ret;
}
int main()
{
	int arr1[10] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
	int arr2[5] = { 0 };
	my_memcpy(arr2, arr1, 20);
	return 0;
}

思路:1.因为memcpy可以复制任何类型的变量,所以必须用void无类型的指针dest和src
2. 写的时候,一个字节一个字节地做
3. 外层循环字节数–,内层先对src强转char*,因为char是一个字节,然后把用星解引用的内容给了强转成char后的dest,最后解引用。然后是两者+1,但是+也得先转为char*,这样才能一个字节一个字节+。
4.最后需要返回dest,即被更改的dest起始,但是经过内层dest已经变了,所以开始的时候先存起来。

2.memmove():重叠内存拷贝

memcpy只适合拷贝两个不同的元素,不可做重叠内层拷贝。
如下图对自己拷贝5个,从位置3起始开,结果得到arr1如右结果,1 2 1 2 1 ,为什么呢?
请添加图片描述
因为之前的源码写法是从头往后拷贝,而从arr1的第三个开始拷贝,arr1的第一个会覆盖arr1第3个值,随后给6位置拷贝3时,已经丢失了,那么这个时候需要memove()

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

memmove做连续地址上的移位。如何复制不会被覆盖,主要是因为重叠,需要考虑从前往后还是从后往前。
如果dest在前而src在后,则从src的头开始往后复制,反之从src的尾->头。
实现

void* my_memmove(void* dest, const void* src, size_t count)
{
	assert(dest && src);
	char* ret = dest;
	//如果dest在前而src在后,则从src的头开始往后复制,反之从src的尾->头。
	// 主要要小心覆盖
	if (dest<src)
	{
		// 前->后
		while (count--)
		{
			*(char*)dest = *(char*)src;
			dest = (char*)dest+1;
			src = (char*)src+1;
		}
	}
	else {
		while (count--)
		{
			// count经过判断已经是19了,src+count是第20元素的起始地址
			*((char*) dest+count) = *((char*)src + count);	// count不断在减少,所以能做完。
		}
	}
	return ret;
}

思路
memmove主要是防止同一段变量地址拷贝的覆盖,所以区分src从头到尾复制和src从尾到头,具体解释看上面吧
结果:
请添加图片描述

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

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