如何使用和何时使用memmove在C?

Kyr*_*rol 12 c function memmove

我对使用memmove()有两个疑问:

  • 什么时候最好使用这个函数而不是使用另一个函数(即创建自己的函数)?我不确定我是否理解得当.
  • 函数的签名是void*memmove(void*dest,const void*src,size_t n).如果我有一个简单的数组arr [N],我怎么能把它放到被调用的函数中?arr [N]或&arr [N]?不同之处在于,数组是以初始大小声明还是像指针一样?我有这个疑问,因为我看到很多例子都用于两者.

我希望我能以一种好的方式解释我的怀疑.

编辑:我必须从数组中删除一个元素,然后我想在左侧移动已删除的元素的以下元素.

Mat*_*lia 17

  1. memmove 可能会更快,但它可能永远不会比你自己的复制数据的功能慢(它通常编码在精心设计的程序集中,以最有效的方式在当前架构上移动东西);
  2. 这取决于你想对该数组做什么...如果你想将其内容复制到另一个数组arr就足够了(并且,作为长度参数,你应该做sizeof(*arr)*NN是要复制的元素的数量).

顺便说一下,如果源和目标以及副本不重叠memcpy可能会更快.

我想从数组中删除一个元素,并向左移动相同数组的元素.

int arr[N];
/* ... */
/* Let's say you want to remove the element i (error checking on i omitted) */
memmove(arr+i, arr+i+1, (N-i-1)*sizeof(*arr));
/* or, if you prefer array indexing over pointer arithmetics: */
memmove(&arr[i], &arr[i+1], (N-i-1)*sizeof(*arr));
Run Code Online (Sandbox Code Playgroud)

(sizeof(*arr)表示"获取数组元素的大小")

  • 请注意,对于非重叠数据,"memcpy"可能更快; 使用`memcpy`也可以记录您在不同对象之间进行复制,而不是在单个数组对象中移动元素. (2认同)

oua*_*uah 6

memmove就像memcpy目的地和源数组可以重叠一样.

memcpy你保证区域不重叠,这允许实现执行一些额外的优化.所以memcpy可以更快memmove.

memmove函数采用void *目标参数和const void *源参数.这意味着您可以使用数组类型的destination和source参数调用该函数,因为它们将转换为指针类型.由于您可以将任何非限定对象指针类型分配给void *const void *,因此在调用函数时不需要任何强制转换.

char src[1024] = {0};
char dst[1024];

memmove(dst, src, sizeof dst);
/* src and dst don't overlap you should choose memcpy instead */
memcpy(dst, src, sizeof dst);
Run Code Online (Sandbox Code Playgroud)

现在通常使用memcpymemmove编写自己的函数更好.以glibc为例,根据MCU指令集和要复制的大小,memcpy可以用编译器替换一些快速的内联汇编版本memcpy.