#include <stdio.h>
#include <stdlib.h>
int* removeNegatives(int *v, int *totv){
int i, j, aux=(*totv), t=0;
for(i=0; i<aux; i++){
if(v[i]<0){
t=v[i];
for(j=i; j<=aux; j++){
v[j]=v[j+1];
}
v[(*totv)-1]=t;
aux--;
i=-1;
}
else{
continue;
}
}
totv=&aux;
v=(int*)realloc(v,(*totv)*sizeof(int));
return(v);
}
int main(){
int *totv=NULL, *v=NULL, *z=NULL, i, j=0, a;
printf("How many numbers are you entering?\n");
scanf("%d",&i);
printf("Enter them, then:\n");
totv=&i;
do{
if(j<(*totv)){
scanf("%d",&a);
v=(int*)realloc(v,++j*sizeof(int));
v[j-1]=a;
}
}while(j<(*totv));
printf("\n");
printf("Size before: %d\n",*totv);
z=retiraNegativos(v,totv);
printf("Size after: %d\n",*totv);
printf("\n");
printf("[ ");
for(i=0; i<(*totv); i++){
printf("%d ",z[i]);
}
printf("]");
printf("\n");
free(z);
return(0);
}
我根据用户输入的负数来调整矢量&#34; v&#34; 的大小。
但问题是,在我调用了函数&#34; removeNegatives&#34; 之后,指针&#34; totv&#34; 没有更新。< / p>
非常感谢您的帮助!
答案 0 :(得分:2)
这可能看起来与您的问题无关,但事实并非如此。
考虑一下:
int foo(int bar)
{
bar = 123;
}
...
int x = 1;
foo(x);
// What's the value of x here?
...
调用x
后会foo
更新吗?
答案 1 :(得分:0)
问题出在这里:
totv=&aux;
您将某些指针的本地副本分配给新地址。这在您的功能之外没有任何明显的效果。你真正想要的不是改变指针,而是它指向的值,因此你需要:
*totv=aux;
此外,您在此处遇到问题:
for(j=i; j<=aux; j++)
v[j]=v[j+1];
在上一次迭代中,您将在位置aux
和aux + 1
处访问阵列,这两个阵列都超出了阵列的范围,至少在第一次删除时!相反,你需要:
for(j = i; j < aux - 1; j++)
或者在我眼中更优雅:
for(j = i + 1; j < aux; j++)
v[j - 1]= v[j];
进一步提示:
else continue;
。i = -1;
),您可以继续使用刚刚复制的值(--i;
)。但是,虽然技术上不正确,但是不要修改for循环的循环变量。这是人们不期望从这种循环中得到的东西。如果你真的需要,那就选择一个while循环。一次性移动所有元素:
int* p = v;
for(unsigned int i = 0; i < aux; ++i)
{
int tmp = v[i];
if(tmp >= 0)
*p++ = tmp; // copy current value to first free position
}
值为{ 1, -2, -3, 4, 5, -6, 7 }
的数组现在看起来像这样:
{ 1, 4, 5, 7, 5, -6, 7 }
。最后的值保持不变,p指向要切断的第一个位置。所以:
aux = p - v;
*totv = aux;
return (int*) realloc(v, aux * sizeof(int));
请注意,如果重新分配失败,您可以通过这种方式返回NULL。如果减小尺寸,我认为这是不太可能的,但是为了正确性:
p = realloc(v, aux * sizeof(int));
return p ? p : v;
因此,您在失败时返回未更改的数组。考虑一些更精细的错误处理......