C/C++ string.h库中memcpy()和memmove()的使用
不能把一个数组赋给另一个数组,所以要通过循环把数组中的每个元素赋给另一个数组相应的元素。有一个例外的情况是:使用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); }
执行结果:
到此这篇关于C/C++ string.h库中memcpy()和memmove()的使用的文章就介绍到这了,更多相关C++ memcpy()和memmove()内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!
相关文章
CreateThread()与beginthread()的区别详细解析
很多开发者不清楚这两者之间的关系,他们随意选一个函数来用,发现也没有什么大问题,于是就忙于解决更为紧迫的任务去了。等到有一天忽然发现一个程序运行时间很长的时候会有细微的内存泄露,开发者绝对不会想到是因为这两套函数用混的结果2013-09-09
最新评论