在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中的内容。输出结果如下:
也可以从数组指定位置开始拷贝。
源地址和目的地址可以重叠。
这两个函数不仅可以拷贝整形数组,还能拷贝其他类型的数据,比如浮点型数组,结构体等。
版权说明 : 本文为转载文章, 版权归原作者所有 版权申明
原文链接 : https://blog.csdn.net/qq_20222919/article/details/121286069
内容来源于网络,如有侵权,请联系作者删除!