2017-06-19 6 views
-1
#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); 
} 

を更新していません。ポインタは、私は、ベクトルのサイズを変更してい<em>、ユーザが入力した負の数の数に応じて「V」</em>

しかし、私はfucntion 「removeNegatives」を呼び出した後、問題がポインタ「のToTV」ことを更新していないされています。

ご協力いただきありがとうございます。

+2

古典的なもの(重複しているもの):パラメータ__including pointers__は、Cで値渡しされます。 –

+0

"更新中"でも、どのように動作すると思いますか? 'removeNegatives'の中で' totv'がローカル変数* aux'を指し示すようにしています。関数が終了すると、そのローカル変数は破棄されます。 – AnT

+0

コードを正しくインデントして、読みやすくしてください。 –

答えて

0

問題はここにある:

totv=&aux; 

あなたが新しいアドレスにいくつかのポインタのローカルコピーを割り当てます。これはあなたの関数の外に目に見える効果はありません。

*totv=aux; 

また、あなたはここに問題があります:最後の繰り返しで

for(j=i; j<=aux; j++) 
    v[j]=v[j+1]; 

を、あなたはどうなるか、あなたが実際に望んでいたことは、あなたが必要なので、ポインタを変更し、それが指す値がされていませんアレイの範囲外で、少なくとも最初の削除時には、auxaux + 1の位置にアクセスしてください。代わりに、あなたが必要とする:私の目には

for(j = i; j < aux - 1; j++) 

またはもう少しエレガントに:

for(j = i + 1; j < aux; j++) 
    v[j - 1]= v[j]; 

さらにいくつかのヒント:存在しない場合は

  • あなたは、任意のelse continue;を必要としませんとにかくelseブランチに従うもの。
  • 最初からループ(i = -1;)を再起動する必要はありません。単にコピーしたばかりの値(--i;)に進むことができます。しかし、技術的に間違っているわけではないが、forループのループ変数を変更したくない。これは、この種のループから期待されないものです。あなたが本当にしなければならない場合は、代わりにwhileループを好む。
  • 削除した値を後で削除する場合は、最後にコピーする必要はありません。
  • 削除した値を残したくない場合は、1つの値を削除するたびにすべての後続の値をコピーしないでください。

    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; 

だからあなたが失敗した場合にそのままの配列を返すと思います。 ...

2

これはあなたの質問と無関係に見えるかもしれませんが、そうではありません。

int foo(int bar) 
{ 
    bar = 123; 
} 
... 
int x = 1; 
foo(x); 
// What's the value of x here? 
... 

xfooへの呼び出しの後に更新されます。

はこの考えてみましょうか?

+1

*でも。 。私はポインタを渡していて、どこかでそれを読んで発信者に変更を見せている*。私は本当にそのような質問に答えることは難しいと思う。 SOにはある程度まで責任があります。いくつかの解答は説明なしで解決策を提供するだけであり、それ以上の議論を制限することは認められています。 *一口* –

関連する問題