【问题标题】:Circular shifting an array with `memmove`使用 `memmove` 循环移动数组
【发布时间】:2017-08-20 17:19:24
【问题描述】:

假设我有一个这样的整数数组

#define MAX 5
int bar [MAX] = {0};
int foo [MAX] = {3,1,0,0,0};

现在我想移动这个数组,使所有空条目都在左边,即bar = {0,0,0,3,1}

我想我可以这样做

  1. 找出我必须执行的轮班次数
  2. 使用memmove() 进行轮班。

我用下面的循环解决了 1.

for (shift = MAX - 1; shift >= 0; --shift) {
    if (foo[shift]) break;
}

但我现在不知道如何使用memmove() 执行轮班,我尝试使用memmove(bar + shift, foo, MAX * sizeof(*foo)-1); 但没有成功。

memmove() 是完成这项工作的正确工具吗?如前所述,如何循环整数数组?如果这发生在 bar 作为指针传递的函数内部怎么办?

【问题讨论】:

  • 如何移入移出的元素?
  • @EugeneSh。我想我需要另一个memmove
  • 显然还有一个中间自助餐来存放它们。
  • @EugeneSh。我需要中间缓冲区吗?我将foo 移动到bar,所以foo 将完好无损,不是吗?我不能再移动foo吗?
  • 对。虽然你想要它就地。在这种情况下,您可以改用memcpy..

标签: c arrays memory memmove


【解决方案1】:
  • 您用来计算shift 的公式没有给出要移动的位置数。

  • 您没有移动正确的字节数(MAX * sizeof(*foo)-1 绝不是基于尾随零的数量)。


#include <string.h>

#define MAX 5
int bar[MAX] = {0};
int foo[MAX] = {3,1,0,0,0};

int i;
int shift = 0;
for (i=MAX; i--; ) {
   if (foo[i]) {
      shift = MAX - (i + 1);
      break;
   }
}

memcpy(bar+shift, foo, (MAX-shift) * sizeof(*foo));
memcpy(bar, foo+(MAX-shift), shift * sizeof(*foo));

您可以就地执行此操作,因为您知道要“轮换”哪些值。

memmove(foo+shift, foo, (MAX-shift) * sizeof(*foo));
memset(foo, 0, shift * sizeof(*foo));

必须使用memmove 而不是memcpy,因为目标缓冲区和源缓冲区可能重叠。

【讨论】:

  • 嗯,在for()之后,shift可以有0, 2, 3,4,5,6的值。并非所有这些值都适用于以下mem...() 代码。
  • @chux 你会怎么解决这个问题?
  • @ikegami,执行上述操作会产生一个“退出代码 139”SIGSEGV。如果bar 是一个指针,我必须在将它传递给memcpy() 时做一些特别的事情吗?
  • 移位估计部分打破了这一点。
  • @BernardoMeurer 我发现你的帖子不清楚。 “所有空条目都在左侧”。 0,1,0,2,0 呢?这个答案可能在正确的轨道上,只需要一个小修复。
猜你喜欢
  • 2016-01-12
  • 1970-01-01
  • 1970-01-01
  • 2016-02-11
  • 2021-12-31
  • 2018-09-10
  • 2017-02-28
  • 2022-06-11
  • 2019-02-20
相关资源
最近更新 更多