一文带你快速了解【memcpy/memmove】使用细则!带你模拟实现函数!

0. memcpy、memmove函数介绍!

0.1 memcpy

在这里插入图片描述
通过cplusplus.com这个网站呢,我们可以查到memcpy参数有3个

第一个参数 代表目的地
第二个参数 代源头
第三个参数 代表多少个字节

由于参数类型是void * 类型,所以在进行复制的时候,是可以任意类型进行复制的!相比strncpy的功能就强大了很多!
下面看下函数实现效果!


int main()
{
	int i = 0;
	int arr[] = { 1,2,3,4,5,6,7,8,9,10 };
	int arr1[5] = { 0 };
	memcpy(arr1, arr, 12);
	for (i = 0; i < 5; i++)
	{
		printf("%d ", arr1[i]);
	}
	return 0;
}

在这里插入图片描述
我们可以看到输出结果为1 2 3 0 0因为第三个参数为12,一个整型为4个字节,12个字节为3个整型,所以这串代码,讲arr数组中前3个元素复制到arr1数组中,最后将arr1数组打印出来。

0.2 memmove

在这里插入图片描述
通过cplusplus.com这个网站呢,我们可以查到memcpy参数有3个

第一个参数 代表目的地
第二个参数 代源头
第三个参数 代表多少个字节

该函数功能更加强大!他可以复制本身的元素到自己这!
下面来看代码实现效果!
在这里插入图片描述
我们可以看到,它将1 2 3复制到了 3 4 5的位置!然后最终arr数组中元素就是1 2 1 2 3 6 7 8 9 10

1. 模拟实现memcpy【不能拷贝本身到本身】

下面让我画个图为大家一起来分析下,代码应该如何写呢?
在这里插入图片描述
首先arr1数组为目的地,arr2数组为源头,分别用指针dest指针src指向

在这里插入图片描述
其次我们将src指向的内容赋值给dest,然后将两个指针分别向后移动,而移动的次数,取决于第三个参数 num。最终就将arr2数组内容复制到arr1数组中!
有了思路以后呢,我们来写代码!

void* my_memcpy(void* dest, const void* src, size_t num)
{
	assert(dest && src);  //判断两个指针是否为空
	while (num--)
	{
		*(char*)dest = *(char*)src;  //因为传的是void*类型,所以要进行强制转换
		dest = (char*)dest + 1;
		src = (char*)src + 1;
	}
}

2. 模拟实现memmove【可以拷贝自身到自身】

我们先来画图分析一下!拷贝自身到自身时候会出现的几种情况

2.1 dest > src

在这里插入图片描述
从图中我们可以看出如果要将5 6 7 8 9 拷贝到 8 9 10 11
在这里插入图片描述
后—>前,只有这样才不会覆盖!

2.2 dest < src

在这里插入图片描述
从图中看出,我们要将5 6 7 8 9 拷贝到 3 4 5 6 7
在这里插入图片描述
前—>后,只有这样才不会覆盖!
经过以上分析之后,我们就有了思考!

2.3 代码实现

2.3.1 dest<src时 代码实现原理和memcpy一模一样

在这里插入图片描述

	while (num--)
	{
		*(char*)dest = *(char*)src;  //因为传的是void*类型,所以要进行强制转换
		dest = (char*)dest + 1;
		src = (char*)src + 1;
	}

2.3.2 dest>src

在这里插入图片描述

while (num--)
		{
			*((char*)dest + num) = *((char*)src + num);
		}

这里因为num进入while循环内部以后,已经减1,所以就不用再减1.

2.3.3 代码最终结合

void* my_memmove(void const* dest, void* src, size_t num)
{
	assert(dest && src);
	if (dest < src)  // 从 前---->后
	{
		while (num--)
		{
			*(char*)dest = *(char*)src;
			dest = (char*)dest + 1;
			src = (char*)src + 1;
		}
	}
	else   //从 后----->前
	{
		while (num--)
		{
			*((char*)dest + num) = *((char*)src + num);
		}
	}
}

2.3.4 运行结果

在这里插入图片描述

3.结束语

如果有疑问,记得评论哦!
在这里插入图片描述

  • 4
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

一个想打拳的程序员

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值