不能把一个数组赋给另一个数组,所以要通过循环把数组中的每个元素赋给另一个数组相应的元素。有一个例外的情况是:使用strcpy()和strncpy()函数来处理字符数组。
memcpy()和memmove()函数提供类似的方法处理任意类型的数组,下面是这两个寒素的原型:
void *memcpy(void *restrict s1, const void *restrict s2, size_t n);
void *memmove(void *s1, const void *s2, size_t n);
这两个函数都从s2指向的位置拷贝n字节到s1指向的位置,而且都返回s1的值。所不同的是memcpy()的参数带关键字restrict,即memcpy()假设两个内存区域之间没有重叠。
而memmove()不做这样的假设,所以拷贝过程类似于先把所有字节拷贝到一个临时缓冲区,然后再拷贝到最终目的地。
如果使用memcpy()时,两区域出现重叠会怎样?其行为时未定义的。这意味着该函可能正常工作。也可能失败。编译器不会再本该不使用memcpy()时禁止你使用,作为程序员,再使用该函数时有责任确保两个区域不重叠。
由于这两个函数设计用于处理任何数据类型,所有它们的参数都是两个指向void的针。
C允许把任何类型的指针赋给void*类型的指针。如此宽容导致函数无法知道待拷贝据的类型。因此这两个函数使用第3个参数指明待拷贝的字节数。
需要注意的时,对数组而言,字节数与元素的个数不同。如果要拷贝数组中10个double
类型的元素,要使用10*sizeof(double),而不是10.
示例源码:
// Len_memcpy.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。
//
#include <iostream>
#define SIZE 10
#include <string>
using namespace std;
void PrintD(string s, int* data, int len)
{
printf("%s\t", s.c_str());
for (int i = 0; i < len; i++)
{
printf("%d\t", data[i]);
}
printf("\n");
}
void PrintD(string s, double* data, int len)
{
printf("%s\t", s.c_str());
for (int i = 0; i < len; i++)
{
printf("%.2lf\t", data[i]);
}
printf("\n");
}
int main()
{
int nValues[SIZE] = { 1,2,3,4,5,6,7,8,9,10 };
double dValues[SIZE] = { 1.1, 2.2, 3.3, 4.4, 5.5,6.6,7.7,8.8,9.9, 0.1 };
int memcpyN[SIZE] = {0}; // 使用memcpy拷贝数据到这里
double memcpyD[SIZE] = {0.0};
int memmoveN[SIZE] = { 0 }; // 使用memmove拷贝数据到这里
double memmoveD[SIZE] = { 0.0 };
printf(" copy before: \n");
PrintD("Values ", nValues, SIZE);
PrintD("dValues ", dValues, SIZE);
PrintD("targetN ", memcpyN, SIZE);
PrintD("targetD ", memcpyD, SIZE);
printf("\n after memcpy copy: \n");
memcpy(memcpyN, nValues, sizeof(int)*SIZE);
memcpy(memcpyD, dValues, sizeof(int)*SIZE); // double比size占位宽,这里会丢失数据
PrintD("Values ", nValues, SIZE);
PrintD("dValues ", dValues, SIZE);
PrintD("memcpyN ", memcpyN, SIZE);
PrintD("memcpyD ", memcpyD, SIZE);
printf("\n after memmove copy: \n");
memcpy(memmoveN, nValues, sizeof(int)*SIZE);
memcpy(memmoveD, dValues, sizeof(double)*SIZE); // 这里不会再丢失数据
PrintD("Values ", nValues, SIZE);
PrintD("dValues ", dValues, SIZE);
PrintD("memmoveN", memmoveN, SIZE);
PrintD("memmoveD", memmoveD, SIZE);
}
执行结果: