了解与模拟实现memmove和memcpy

memcpy:

第一步:了解memcpy:

memcpy(数组a,数组b,多少个字符c)

就是将数组b中的第一个元素开始,向后数的c个字符与数组a的第一个元素开始向后数c个字符进行替换。

一个例子:

#include<stdio.h>
#include<string.h>
int main()
{
	int arr[] = { 1,2,3,4,5,6,7,8 };
	int brr[30] = { 0,2,8 };
	memcpy(brr, arr, 2 * sizeof(arr[0]));
	for (int i = 0; i < 20; i++)
	{
		printf("%d ", brr[i]);
	}
	return 0;
}

我们就可以看到arr数组的第一个和第二个元素1,2替换了brr数组中的第一个元素和第二个元素,同时这里的2*sizeof(arr【0】)可以直接写成8,一个int=4,替换两个就是8,也可以像我一样写成2*sizeof(arr【0】);

第二个例子:

#include<stdio.h>
#include<string.h>
int main()
{
	int arr[] = { 1,2,3,4,5,6,7,8 };
	int brr[30] = { 0,2,8,9,5 };
	memcpy(brr+1, arr+2, 2 * sizeof(arr[0]));
	for (int i = 0; i < 20; i++)
	{
		printf("%d ", brr[i]);
	}
	return 0;
}

 

 

 我第二个例子就修改了brr+1,与arr+2,意思就是将从arr+2开始的2*sizeof(arr【0】)个元素(就是arr【2】开始)替换给brr+1(brr【1】)开始的2*sizeof(arr【0】)个元素

模拟实现memcpy:

void* mymemcpy(void* a, const void* b, int width)

我们作为memcpy的作者,不知道使用者会拿什么类型进行替换,所以a数组与b数组都是void*类型,而b数组不用改变,所以为了安全加上const修饰,最后加上一个宽度int width

因为返回void*所以我们首先讲a数组的首地址存储,然后为了安全加上assert函数

void* res = a;
	assert(a && b);

 因为最少单位是char,所以替换,我们强制转换到最小char类型,然后一个字节一个字节替换

	while (width--)
	{
		*(char*)a = *(char*)b;
		a = (char*)a+1;
		b = (char*)b+1;
	}

总代码:

#include<assert.h>
void* mymemcpy(void* a, const void* b, int width)
{
	void* res = a;
	assert(a && b);
	while (width--)
	{
		*(char*)a = *(char*)b;
		a = (char*)a+1;
		b = (char*)b+1;
	}
	return res;
}
#include<stdio.h>
#include<string.h>
int main()
{
	int arr[] = { 1,2,3,4,5,6,7,8 };
	int brr[30] = { 0,2,8,9,5 };
	mymemcpy(brr+1, arr+2, 2 * sizeof(arr[0]));
	for (int i = 0; i < 20; i++)
	{
		printf("%d ", brr[i]);
	}
	return 0;
}

模拟实现memmove:

因为memmove的原理和memcpy的原理一模一样,区别就在于,memmove能够替换重复而memcpy不能,所以我这里直接模拟实现memmove。

如果a数组的地址小于b数组的地址,那么memmove和memcpy一模一样,我这里就讲一下a数组的地址大于b数组的地址的情况,如图↓

 

 

 

 

 我们可以看见b数组和a数组有一个交集,我们运行时,b数组的‘4’就会替换a数组中的‘1’;

 然后我们就会发现,这时候原本应该拿b数组的‘1’去替换a数组的‘2’,变成了‘4’去替换‘2’。

这就出问题了,所以

while (width--)
		{
			*((char*)a + width) = *((char*)b + width);
		}

 我们这里还是强制转换为char类型,当width进来的时候,作为字符他已经减了1,

所以*((char*a)+width)表示的是

a数组中倒数第一个字符的位置和b数组倒数第一个字符的位置交换

总代码:

#include<stdio.h>
#include<string.h>
#include<assert.h>
void* mymemmove(void* a, const void* b, int width)
{
	assert(a && b);
	void* res = a;
	if (a < b)
	{
		while (width--)
		{
			*(char*)a = *(char*)b;
			a = (char*)a + 1;
			b = (char*)b + 1;
		}
	}
	else
	{
		while (width--)
		{
			*((char*)a + width) = *((char*)b + width);
		}
	}
	return res;

}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值