C数组,向右移动元素不能按预期工作

时间:2014-09-25 17:44:48

标签: c arrays for-loop

我试图将数组中每个元素的位置向右移动1以插入一个新对象并且它没有按预期工作,这个代码有什么问题? 编辑:它用新的obj替换第一个元素,并在插入将转到数组的第一个索引的内容时删除最后一个元素。该阵列具有1020个对象的容量,目前阵列中有14个

for(i = 0; i < *size; i++){
      if((obj.ID < array[i].ID) || (obj.ID < array[i].ID)){
        size_t j;
        for(j = *size-1; j > i-1; j--){
          array[j] = array[j-1];//array[j+1] = array[j];
        }
        array[i] = obj.ID;
        *size = *size + 1;
        return array;
      }
    }

3 个答案:

答案 0 :(得分:0)

最外层循环的第一次迭代,i = 0

for(j = *size-1; j > i-1; j--)

此循环将从size - 1转到i(包括i值),因此当j在最后一次迭代中变为0时,内部的赋值语句看起来像这样

 array[0] = array[-1];

那就是问题所在

答案 1 :(得分:0)

你的代码对我没有多大意义。如果您想要做的是将所有元素向右移动一个,那么您应该首先考虑的是最后一个元素应该发生什么。它应该丢失吗?我们应该增长阵列吗?只有在使用malloc动态分配数组时才能执行后者。

我们假设我们愿意丢失长度为n - 1的数组array中的最后一个元素(位置n)。以下是我们如何转变:

int i;
for (i = n - 1; i > 0; --i)
  array[i] = array[i - 1];

请注意,我们从数组的末尾开始并向开头方向移动。 (你能想象会发生什么吗?)

如果您想获得最佳性能,请考虑使用memmove而不是自动循环,但从手动操作开始有助于更好地理解。

<强>更新

  

你怎么做才能让最后一个元素掉线?如果可能的话

复制是相同的,除了循环以n而不是n - 1开头。但是,这仅在数组的大小为n + 1时才有效。如果您提前知道元素的最大数量,则可以预先创建足够大的数组。但是,很多时候,你不会知道它,这就是你必须使用动态内存的时候。

您可以通过

分配足够大的缓冲区来保存n类型的int个变量
int * buffer = malloc(n * sizeof(int));
if (buffer == NULL)
  {
    fprintf(stderr, "error: out of memory\n");
    abort();
  }

并重新调整大小以便稍后通过

保留m个元素
int * tmp = realloc(buffer, m * sizeof(int));
if (tmp == NULL)
  {
    fprintf(stderr, "error: out of memory\n");
    abort();
  }
else
  {
    buffer = tmp;
    /* 'buffer' can now hold 'm' integers. */
  }

如果这样做,请避免逐个更改大小,因为效率非常低。而是在两个单独的变量中跟踪当前容量和当前使用的大小,并始终将容量调整为2倍。

在您不再需要缓冲区后,请将其返回系统:

free(buffer);

我最近发布了管理这样一个动态数组的a working example作为另一个问题的答案。也许你会发现它也很有用。

答案 2 :(得分:0)

无符号整数环绕。

for(j = *size-1; j > i-1; j--){

jsize_t类型,因此j > i-1肯定是2个无符号类型的比较。自i=0开始,比较为j > some_very_large_unsigned_value

未经检查的解决方案可能是向双方添加1。

   for(j = *size-1; j+1 > i; j--){
      array[j] = array[j-1];
    }
    // or simply
   for(j = *size; j-- > i; ){
      array[j] = array[j-1];
    }

预先增加尺寸:

    if (*size >= 1020) Handle_TooMany();        
    *size = *size + 1;
    for(j = *size; j-- > i; ){
      array[j] = array[j-1];
    }