C语言学习笔记---数据拷贝函数memcpy()和memmove()函数

492 阅读4分钟

「这是我参与2022首次更文挑战的第3天,活动详情查看:2022首次更文挑战」。

  在C语言中拷贝字符串的时候通常可以使用strcpy()函数和strncpy()函数,这两个函数是专门针对字符串拷贝的。如果想要拷贝其他类型数组的话,可以使用memcpy()和memmove()函数。 下面就来看一下这两个函数的使用方法。

memcpy()函数

  函数原型如下:

void * __cdecl memcpy(void * __restrict__ _Dst,const void * __restrict__ _Src,size_t _Size)

  这个函数有三个参数,第一个是目标数组的地址,第二个是源数组的地址,第三个是要拷贝的字节数。这个字节数不是指的元素个数,而是元素所占的总空间大小。比如对于一个 int 型数组而言,如果要拷贝5个元素,那么第三个参数就要填 5 * sizeof(int),而不是5。

  前两个参数里面都带有关键字 restrict ,restrict 用来定义指针变量,表明该变量没有别名,意思就是:除了该变量以外,没有别的方法可以访问其指向的地址空间。也就是拷贝的两个数组地址不能重叠,在拷贝的过程中会直接将源地址的数据拷贝的目的地址,而不是先将数据拷贝到缓存区,然后在拷贝到目的地址。所以使用memcpy()函数拷贝数据的时候,一定要确保两个地址没有重叠,否则就会出现未知的错误。

  下面通过一个例子来演示:

int value1[10] = {0,1,2,3,4,5,6,7,8,9};
int value2[10];
int main()
{
	int n = 0;
	memcpy(value2,value1,10*sizeof(int));

	for(n=0; n<10; n++)
		printf("%d ",value2[n]);

	system("pause");
	return 0;
}

  将数组1的内容拷贝到数组2中,然后打印数组2中的内容。输出结果如下:

在这里插入图片描述

  如果源地址和目的地址重叠,会发生怎样的情况?

在这里插入图片描述

  将value1数组的值拷贝到value1数组中,从输出的结果来看,value1中的值也正常输出了。但是地址重叠后函数输出的结果是未知的,有可能数据正确,也有可能数据不正确。所以尽量避免地址重叠。

  在拷贝数据的时候不一定都从数据的起始位置开始,也可以设置从指定的位置开始。比如修改代码如下:

int value1[10] = {0,1,2,3,4,5,6,7,8,9};
int value2[10];
int main()
{
	int n = 0;
	memcpy(value2+5,value1+3,5*sizeof(int));

	for(n=0; n<10; n++)
		printf("%d ",value2[n]);
	system("pause");
	return 0;
}

  从value1数组中第3个元素开始,拷贝5个元素到value2数组中第5个元素位置开始处。打印结果如下:

在这里插入图片描述

  可以看到value2数组中前5个元素都是0,后面5个元素的值是value1中第3个元素开始的数字。

memmove()函数

  函数原型是:

void *__cdecl memmove(void *_Dst,const void *_Src,size_t _Size) 

  memmove()函数原型和memcpy()函数原型基本一样,只是参数里面没有关键字__restrict__ ,说明这个函数在拷贝数据的时候,是不检测地址的,它会先将数据拷贝到一个临时的缓冲区中,然后从缓冲区中再将数据拷贝出去。所以用它拷贝数据的时候,就是地址有重叠,也不会破坏数组中原有的数据。

  下面使用代码来测试:

int value1[10] = {0,1,2,3,4,5,6,7,8,9};
int value2[10];
int main()
{
	int n = 0;
	memmove(value2,value1,10*sizeof(int));
	for(n=0; n<10; n++)
		printf("%d ",value2[n]);
	system("pause");
	return 0;
}

  将数组1的内容拷贝到数组2中,然后打印数组2中的内容。输出结果如下:

在这里插入图片描述

  也可以从数组指定位置开始拷贝。

在这里插入图片描述

  源地址和目的地址可以重叠。

在这里插入图片描述

  这两个函数不仅可以拷贝整形数组,还能拷贝其他类型的数据,比如浮点型数组,结构体等。