memcpy、memmove

前言

一、memcpy

1.介绍

2.使用

3.模拟实现

二、memmove

1.介绍

2.模拟实现

三、总结

扫描二维码关注公众号,回复: 16153664 查看本文章


前言

上一文,学习了字符串相同函数的使用,在某些场合,数据的类型不限于字符串,有可能是整形,浮点型甚至是自定义类型,所以内存函数(memcpy、memmove)就能实现数据的拷贝和移动

本文依就从函数的使用和模拟实现来介绍内存函数

一、memcpy

1.介绍

函数的作用是拷贝

函数的原型是含有三个参数,第一个参数为拷贝的目的地,第二个为拷贝的来源,第三个为拷贝的字节数。它将返回拷贝后数据的起始位置

同样的,必须包含memory.h或者string.h头文件

2.使用

接下来通过一个简单例子,理解memcpy的使用

 创建了一个结构体类型,将s1内容拷贝给s2

memcpy函数的第一个参数为目的地地址,第二个参数为来源地址,第三个参数为来源内容的字节

3.模拟实现

思路:

要实现任意类型,那么函数的前俩个参数必须是void* 这样才能接收各种参数,其返回类型也必须是void* 

拷贝---赋值,每次赋过去一个字节,之后让指针往后走一字节。

由于void*指针不能加减,所以必须将其强制类型转换为char*

那就来看看代码吧

void* my_memcpy(void* des, const void* sour, size_t num)
{
	assert(des && sour);
	void* head = des;
	while (num--)
	{
		*(char*)des = *(char*)sour;
		des = (char*)des+1;
		sour = (char*)sour+1;
	}
	return head;
}

二、memmove

在strcat、strcpy中,不能自己追加自己,因为会把'\0'覆盖掉

类似的,memcpy想要拷贝自己的内容,也会出现失败

例如,有以下代码

我们想得到的预期结果应该是1 2 1 2  3  4  7

而实际上却得到  1 2  1 2 1 2  7

原因也很简单,在memcpy拷贝时,是一个字节一个字节的拷贝 

 在拷贝第三个数字,原本的数字3已经被覆盖为1,所以就得不到想要的结果

所以想要得到正确的结果就可以用memmove

1.介绍

这回就能得到我们想要的结果1 2 1 2 3 4 7

 memmove函数参数有三个,第一个是目标位置地址,第二个是来源地址,第三个参数是拷贝的字节数目,返回类型是void*。该函数可以接收或者返回任意类型的数据

2.模拟实现

思路:

对于一个数组内容为

1 2 3 4 5 6 7,我们想将3级往后的3个元素拷贝到1 ,从3开始一个字节一个字节的拷贝是没有问题

但是想将1及往后的4个元素1 2 3 4 从1一开始拷贝到3 4 5 6上,就无法实现,其原因和strcat类似,会出现字符串覆盖。但是我们可以反过来,先拷贝4 ,在拷贝3,在拷贝2,最后拷贝1,就不会出现覆盖的问题。

根据这个想法,我们把元素分成俩种情况  

  • 从前往后拷贝--------从源 起始位置一个一个拷贝至最后一个元素
  • 从后往前拷贝--------从源 某位置一个一个往前拷贝

上述就可以解决覆盖的问题

还有一类不存在覆盖,即从前往后拷贝和从后往前拷贝不影响结果,我们可以将这一类归到俩种的任一种。本文贵在第二种,代码较为简洁。

举例:从后往前拷贝,条件是des<sour 

就有这些铺垫,那么我们就可以来模拟实现 

void* my_memmove(void* des, void* sour, size_t num)
{
	assert(des && sour);
	const void* head = des;
	//从前往后移动
	if (sour > des)
	{
		while (num--)
		{
			*(char*)des = *(char*)sour;
			des = (char*)des + 1;
			sour = (char*)sour + 1;
		}
	}
	else//从后往前拷贝
	{
		while (num--)
		{
			//找到最后的位置
			*((char*)des + num) = *((char*)sour + num);
		}
	}
	return head;
}

三、总结

在拷贝时,不要使用memcpy自己拷贝自己,这种情况用memmove。

memmove的思想依旧涉及较高的指针,值得大家练习。

最后,感谢大家的阅读。

我是小凡,欢迎大家提出宝贵的见解。

代码++

offer++

猜你喜欢

转载自blog.csdn.net/m0_73299809/article/details/129553157
今日推荐