2017-06-19 106 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); 
} 

我正在根據用戶輸入的負數來調整矢量「v」的大小。指針沒有更新

但問題是,指針「ToTV的」沒有更新後,我稱之爲溫控功能「removeNegatives」

非常感謝您的幫助!

+2

經典之一(幾十個重複項):參數__including指針__按值傳入C. –

+0

即使它正在「更新」,您會如何期待它的工作?在'removeNegatives'裏面,你讓'totv'指向一個*局部變量*'aux'。當局部變量在函數結束時被銷燬。 – AnT

+0

請正確縮進您的代碼,以便它更具可讀性。 – 2017-06-19 15:32:28

回答

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循環。
  • 無論如何你都不需要將刪除的值複製到最後。
  • 如果您不想保留已刪除的值,請不要在每次刪除一個值時複製所有後續值,而是希望複製每個值以保留一次,如下所示。

移動一氣呵成的所有元素:

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? 
... 

x調用foo後更新?

+1

*但是。 。我正在傳遞指針,並且我在某處讀取它導致調用者看到更改*。我真的很難回答這樣的問題。 SO在某種程度上對此負責。有些答案只是提供一個解決方案,沒有任何解釋,並得到接受限制進一步討論*嘆* –