string.h库中的mencpy()和memmove()函数
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#define SIZE 10
void show_array(const int ar [], int n);
// 如果编译器不支持C11的_Static_assert,可以注释掉下面这行
_Static_assert(sizeof(double) == 2 * sizeof(int), "double not twice int size");
int main(){
int values[SIZE] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
int target[SIZE];
double curious[SIZE / 2] = { 2.0, 2.0e5, 2.0e10, 2.0e20, 5.0e30 };
puts("memcpy() used:");
puts("values (original data): ");
show_array(values, SIZE);
memcpy(target, values, SIZE * sizeof(int));
puts("target (copy of values):");
show_array(target, SIZE);
puts("\nUsing memmove() with overlapping ranges:");
memmove(values + 2, values, 5 * sizeof(int));
puts("values -- elements 0-4 copied to 2-6:");
show_array(values, SIZE);
puts("\nUsing memcpy() to copy double to int:");
memcpy(target, curious, (SIZE / 2) * sizeof(double));
puts("target -- 5 doubles into 10 int positions:");
show_array(target, SIZE / 2);
show_array(target + 5, SIZE / 2);
}
void show_array(const int ar [], int n){
int i;
for (i = 0; i < n; i++)
printf("%d ", ar[i]);
putchar('\n');
}
共同点
都从s2指向的位置拷贝n字节到s1指向的方向,而且都返回s1的值
设计用于处理任何函数
不同点
memcpy函数参数带关键字restrict
memcpy()假设两个内存区域之间没有重叠;memmove()则不做这种假设,所以拷贝过程类似于先把所有字节拷贝到一个临时缓冲区,然后再拷贝到最终目的地,这两个函数的第三个参数指明待拷贝的字节数
如果要拷贝10个double类型要使用10*sizeof(double)。而不是10
memcpy()
函数原型
void*memcpy(void*restrict s1, const void*restrict s2, size_t n);
不能对本身进行覆盖拷贝
不知道也不关心数据的类型,只负责从一个位置把一些字节拷贝到另外一个位置,拷贝过程中也不会进行数据转换,
用于内存复制。第一个是目标地址,第二个是源地址,第三个数据长度
数据长度的单位是字节都要使用 n*sizeof(type_name)的写法
该函数的返回值类型是void* 是个指向restrict的指针
应用
int values[SIZE] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
int target[SIZE];
double curious[SIZE / 2] = { 2.0, 2.0e5, 2.0e10, 2.0e20, 5.0e30 };
puts("memcpy() used:");
puts("values (original data): ");
show_array(values, SIZE);
memcpy(target, values, SIZE * sizeof(int));
puts("target (copy of values):");
show_array(target, SIZE);
输出
memcpy() used:
values (original data):
1 2 3 4 5 6 7 8 9 10
target (copy of values):
1 2 3 4 5 6 7 8 9 10
memmove()
能对本身进行覆盖拷贝,同时兼备了memcpy的功能;在有些编译器下,两个函数能实现相同的功能
函数原型
void *memmove(void *dest, const void *source, size_t count)
//
memmove(values + 2, values, 5 * sizeof(int));
//输出:1 2 1 2 3 4 5 8 9 10
参数说明:dest,src分别为目标串和源串的首地址。count为要移动的字节的个数
函数说明:memmove用于从src拷贝count个字节到dest;如果目标区域和源区域有重叠的话,memmove能够保证源串在被覆盖之前将重叠区域的字节拷贝到目标区域中