模拟实现memcpy

理解memcpy

在cplusplus中对该函数的解释见下图

我们可以看出该函数有三个参数:1.destiation 为需要被覆盖目标的地址,2.source为需要复制的内容的地址,3.num为需要复制的字节数。

下面我们以 int 数组为例

下图中 arr1为目标地址,arr2为需要复制的内容

当我们需要将arr2[ 1 ]的内容复制到arr1[ 1 ]时,首先我们需要 arr1[ 1 ]和 arr2[ 1 ] 的地址。我们知道 int 类型参数的大小为 4 字节并且我们需要复制的元素只有一个,所以 num 的值为 4 。故函数应该这样写:memcpy(arr1, arr2, 4) 

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

执行后arr1与arr2的内容如下图

 

 我们再以 char 类型为例

我们创建两个字符数组 str1 与 str2 

我们如果需要将"wxyz" 覆盖 "defg",需要找到 字符 'd' 的地址和字符 'w' 的地址即可。字符'd'的地址为 str1 + 3,  w为str2首元素所以直接写str2即可,因为 char 类型的大小为 1 字节,我们需要复制的元素个数为 4 个 ,所以 num 的值也只能为 4 ,所以函数的写法为:

memcpy(str1+3, str2, 4)

int main()
{
	char str1[10] = { 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', '\0' };
	char str2[5] = { 'w', 'x', 'y', 'z', '\0' };
	memcpy(str1 + 3, str2, 4);
	for (int i = 0; i < 10; i++)
		{
			printf("%c ", str1[i]);
		}
	return 0;
}

 

 

从中我们不难看出,memcpy函数所操作的是内存本身,与数据的类型(int,char,float)无关。

函数只将 目标内容 与 需要复制的内容一一替换。最后再将其转换成所需要的类型就达成目的了。

所以 num 的值需要自行计算,且其公式为

num =(元素类型的大小 * 需要复制的元素个数)


模拟实现

分析

1.因为我们是模拟函数实现,所以我们创建的函数所需要的参数应该与被模拟函数一样。

2.根据函数工作原理,我们可以推测出,函数只将内存中的内容覆盖,并未做其他修改,所以我们只需将(void*)转换成 (char*)类型解引用后赋值即可达到一次目的。

3.因为每次只操作一个字节,所以需要进行 num 次循环。

所以最终代码为:

#include <assert.h>
void my_memcpy(void* str1, const void* str2, size_t sz)

{
	while (sz)
	{
		assert(str1 && str2);
		*(char*)str1 = *(char*)str2;  //转换成(char*)再解引用即每次访问一个字节以达到内容一一对应的目的,且由于是函数接收的是void*类型无法直接解引用
		((char*)str1)++; //((char*)str1)++与(char*)str1++存在符号优先级的问题,我们应该先转换成(char*)类型在++
		((char*)str2)++;
		sz--;
	}
}

思考

该函数能否用于地址存在重复的情况 如 arr1[10] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 },我们将4,5,6,7,8复制到5,6,7,8,9中?或者将5,6,7,8,9复制到4,5,6,7,8?

答案是前者不行后者可以,对此有兴趣的老铁请关注笔者的后续内容~~

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值