我试图将数组中每个元素的位置向右移动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;
}
}
答案 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--){
j
是size_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];
}