要将数组复制b[]
到数组a[]
中,可以使用memcpy
以下函数;
memcpy(a,b,sizeof(a))
.
但memcpy
只是将字节从一个地方复制到另一个地方。
我的问题是:
1.如何通过复制字节来复制数组的
memcpy
元素? 2.为什么作为参数提供?b[]
a[]
sizeof(a)
我是编程新手,所以要温柔。
sizeof(a)
是数组的总大小a
。例如,在
int a[3];
printf("%d", sizeof(a));
sizeof a
将12
在大多数系统上(因为int
通常是 4 个字节,而你有 3 个)。
memcpy
不知道那a
是一个数组。它所知道的只是a
指向某个内存地址,所以你必须告诉它要传递多少字节。大多数地方将 memcpy 的签名描述为:
void *memcpy(void *dst, const void *src, size_t nbytes)
#include <string.h>
void *
memcpy(void *s1, const void *s2, register size_t n)
{
register char *p1 = s1;
register const char *p2 = s2;
if(n) {
n++;
while (--n > 0) {
*p1++ = *p2++;
}
}
return s1;
}
这是 memcpy 的源代码。正如你所看到的,它从寄存器 1 中逐个遍历每个元素,并将其逐个移入寄存器 2。
使用 size of 所以它知道寄存器有多大,所以基本上在复制整个寄存器之前它必须跳过多少元素。
memcpy
就像汇编指令的MOV
工作原理一样(显然,memcpy
必须使用 来实现MOV
)。不同之处在于,我们移动的是一个数据块,而不是一个变量。由于进程需要知道要从一个位置复制到另一个位置的字节数,因此需要块的大小。
1)在C语言中,所有数组实际上只是一个长序列中的数据字节,一个接一个。没有散布的元数据或类似的东西,因此复制数组的字节意味着复制数组本身而不会丢失数据,无论数组由什么类型组成。只有总大小很重要。
2)正如Kerrek SB所说,“因为你不能在C中拥有数组类型的函数参数”。这与 1 相关 - 由于 C 数组中没有元数据,因此该函数无法获取有关数组有多大的信息,只是它在内存中的起始位置。大小使它可以知道何时停止写入数据。
Sizeof(a) 作为第三个参数提供,因为它是数组 a 的大小(以字节为单位)。事实上,使用数组作为参数调用的 sizeof 会返回该数组中的总字节数,而不是数组标识符表示的指针的大小。
第一个是一个有趣的问题。是的,它是一个简单的二进制副本,但复制的顺序很重要。比如说,如果你有一个重叠的区域,并且 &a[0] > &b[0],会发生什么?如果是从左到右,memcpy 会在复制时简单地覆盖 b[] 中的数据。
AFAIK,任何标准都没有指定特定的复制顺序,建议使用 memmove 作为更安全的选择,但仍然如此。