16.12 string.h库中的memcpy( )和memmove( )

不能把一个数组的值直接赋予另一数组,因此,我们使用循环把数组中的元素逐个复制到另一数组。一个例外情况是:可以使用strcpy()和strncpy()函数复制字符数组。memcpy()和memmove()函数为复制其他类型的数组提供了类似的便利工具。下面是这两个函数的原型:

阅读 ‧ 电子书库

广告:个人专属 VPN,独立 IP,无限流量,多机房切换,还可以屏蔽广告和恶意软件,每月最低仅 5 美元

这两个函数均从s2指向的位置复制n字节数据到s1指向的位置,且均返回s1的值。两者间的差别由关键字restrict造成,即memcpy()可以假定两个内存区域之间没有重叠。memmove()函数则不作这个假定,因此,复制过程类似于首先将所有字节复制到一个临时缓冲区,然后再复制到最终目的地。如果两个区域存在重叠时使用memcpy()会怎样呢?其行为是不可预知的,即可能正常工作,也可能失败。在不应该使用memcpy()时,编译器不会禁止使用memcpy()。因此,使用memcpy()时,您必须确保没有重叠区域。这是程序员的任务的一部分。

这两个函数可对任何数据类型进行操作,因此两个指针参数为void类型指针。C允许将任何类型的指针赋值给void*类型指针。接受各种类型指针导致函数无法知道要复制的数据类型。因此,这两个函数使用第三个参数来指定要复制的字节数。注意,对数组而言,字节数一般不等于元素的个数。因此,如果复制10个double值组成的数组,那么应使用10*sizeof(double)作为第三个参数,而不应使用10。

程序清单16.17显示了一些使用这两个函数的示例。

程序清单 16.17 mems.c程序

阅读 ‧ 电子书库

阅读 ‧ 电子书库

输出如下:

阅读 ‧ 电子书库

最后一次memcpy()调用把数据从double数组复制到int数组。这表明memcpy()不知道也不关心数据类型;它只是把一些字节从一个位置复制到另一个位置(例如,可以从结构中复制字节到字符型数组)。复制过程中也不进行数据转换。如果使用循环对元素逐个赋值,那么在赋值过程中会将double类型值转换为int类型值。此时,对字节按原样进行复制,然后程序将把数据作为int类型进行解释。