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

Ich Ändern der Größe des Vektors „v“ entsprechend der Anzahl der negativen Zahlen der Benutzer eingegeben hat.Zeiger nicht

Aber das Problem ist, dass der Zeiger „totv“ wird nicht aktualisiert, nachdem ich die fucntion „removeNegatives“ nennen.

Ihre Hilfe wird sehr geschätzt!

+2

Ein Klassiker (Dutzende von Duplikaten): Parameter __ einschließlich Zeiger__ werden durch Wert in C übergeben. –

+0

Selbst wenn es "Aktualisierung" wäre, wie würden Sie erwarten, dass es funktioniert? Innerhalb von 'removeNegatives' machen Sie Ihr' totv' so, dass es auf eine * lokale Variable * 'aux' zeigt. Diese lokale Variable wird zerstört, wenn die Funktion beendet ist. – AnT

+0

Bitte den Code richtig einrücken, damit er besser lesbar ist. –

Antwort

0

Problem ist hier:

totv=&aux; 

Sie Ihre lokale Kopie von etwas zu einer neuen Adresse Zeiger zuweisen. Dies hat keine sichtbaren Auswirkungen außerhalb Ihrer Funktion. Was Sie wollten eigentlich den Zeiger nicht ändert, aber der Wert verweist er auf, so benötigen Sie:

*totv=aux; 

Zusätzlich Sie ein Problem haben hier:

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

In der letzten Iteration, werden Sie Zugriff auf Ihr Array an den Positionen aux und aux + 1, beide außerhalb der Reichweite Ihres Arrays, zumindest bei der ersten Entfernung! Stattdessen müssen Sie:

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

oder ein wenig mehr elegant in meinen Augen:

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

Einige weitere Hinweise:

  • Sie keine else continue; brauchen, wenn es nicht ist alles, um dem else-Zweig trotzdem zu folgen.
  • Keine Notwendigkeit, die Schleife (i = -1;) von Anfang an neu zu starten, können Sie einfach mit dem Wert gehen Sie gerade kopiert (--i;). Sie sollten die Schleifenvariable einer for-Schleife jedoch nicht verändern, auch wenn sie technisch nicht inkorrekt ist. Das ist etwas, was man von dieser Art von Schleife nicht erwartet. Wenn Sie wirklich müssen, dann bevorzugen Sie stattdessen eine While-Schleife.
  • Sie müssen die entfernten Werte nicht zum Ende kopieren, wenn Sie sie danach trotzdem abschneiden.
  • Und wenn Sie die entfernten Werte nicht beibehalten möchten, kopieren Sie nicht alle nachfolgenden Werte jedes Mal, wenn Sie einen Wert entfernen, sondern kopieren Sie jeden Wert, der nur einmal gespeichert werden soll, siehe unten.

alle Elemente in einem Rutsch Umzug: { 1, 4, 5, 7, 5, -6, 7 }:

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 
} 

Ein Array mit Werten { 1, -2, -3, 4, 5, -6, 7 } nun wie folgt aussehen würde.Die letzten Werte bleiben unverändert, p zeigt auf die erste abzuschneidende Position. Also:

aux = p - v; 
*totv = aux; 
return (int*) realloc(v, aux * sizeof(int)); 

Beachten Sie, dass Sie NULL auf diese Weise zurückkehren könnte, wenn Neuzuweisung fehlschlägt. Ich würde davon ausgehen, das sehr unwahrscheinlich sein, wenn eine Größe zu reduzieren, aber für Richtigkeit:

p = realloc(v, aux * sizeof(int)); 
return p ? p : v; 

So würden Sie die unveränderte Array bei einem Fehler zurück. Betrachten Sie einige mehr fein abgestimmte Fehlerbehandlung ...

2

Dies kann unabhängig von Ihrer Frage aussehen, aber es ist nicht.

diese Bedenken Sie:

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

Wird x nach dem Aufruf foo aktualisiert werden?

+1

* Aber aber. . Ich übergebe den Zeiger und ich lese irgendwo, dass der Anrufer die Änderungen sieht *. Ich finde es wirklich schwierig, solche Fragen zu beantworten. Zum Teil ist SO dafür verantwortlich. Einige Antworten liefern nur eine Lösung ohne jegliche Erklärung und werden akzeptiert, was die weitere Diskussion einschränkt. *Seufzer* –