2017-03-21 6 views
1

Ich habe ein Programm für eine Klasse geschrieben und habe ein Problem. Der Zweck des Programms besteht darin, eine Reihe von Werten in ein Array zu lesen, den Durchschnitt zu berechnen und dann zu ermitteln, wie viele Elemente in diesem Array größer als dieser Durchschnitt sind. Die Funktionsprototypen wurden zur Verfügung gestellt, so dass sie nicht geändert werden können. Außerdem wurden wir angewiesen, das Array auf die Größe 10 zu initialisieren und die Größe zu verdoppeln, wenn die Anzahl der gelesenen Elemente die aktuelle Größe überschreitet, so dass sie nicht geändert werden kann.

Das Problem, bei dem ich gerade laufe, ist die Rückgabe eines Wertes aus der obigen Durchschnittsfunktion. Es funktioniert ordnungsgemäß in sich selbst (ich kann ein printf auf die Anzahl der Anzeigen vor der Rückkehr setzen, aber in der Hauptfunktion ist der zurückgegebene Wert 0. Gibt es jemanden, der dabei helfen kann? Es wird frustrierend.
die kommentierte printf Linie um den Wert zu überprüfen, war von der Funktion zurückgegeben wird. ich bemerkte es stattdessen, um es zu löschen, so würde ich es nicht jedes MalC Funktion gibt keinen Wert zurück

#include <stdio.h> 
#include <stdlib.h> 

double average(double *ptr, int size); 
int aboveaverage(double *ptr, int size, double average); 

int main(int argc, char* argv[]) 
{ 
    double *ptr, avg, above, temp; 
    int size = 10, i, j; 
    void *tmp; 
    FILE *fp; 

    avg = above = 0; 

    if (argc != 2) 
    { 
     printf("Invalid number of arguments, 2 required\n"); 
     return 1; 
    } 

    fp = fopen(argv[1], "r"); 
    ptr = (double *)calloc(10, sizeof(double)); 
    printf("Allocated 10 doubles\n"); 

    for (i = 0;fscanf(fp, "%lf", &temp) != EOF; i++) 
    { 
     if (i >= size - 1) 
     { 
      size*=2;  
      tmp = realloc(ptr, size); 
      if (tmp == NULL) 
      { 
       printf("Error with realloc, exiting\n"); 
       return 1; 
      } 
      printf("Reallocated to %d doubles\n", size); 
     } 
     ptr[i] = temp; 
     j = i; 
    } 

    size = j + 1; 
    avg = average(ptr, size); 
    above = aboveaverage(ptr, size, avg); 
    //printf("%d\n", above); 

    printf("%d elements are above average of %lf\n", above, avg); 

    free(ptr); 

    return 0; 
} 

double average(double *ptr, int size) 
{ 
    double sum; 
    int i; 
    while (i < size) 
    { 
     sum+=ptr[i]; 
     i++; 
    } 

    return (sum/size); 
} 

int aboveaverage(double *ptr, int size, double avg) 
{ 
    int count=0, temp; 
    for (int i = 0; i < size; i++) 
    { 
     temp = (int)ptr[i]; 
     if (temp > avg) 
     count++; 
    } 
    return count; 
} 
+1

Das hilft nicht bei Ihrem Problem, aber Ihr Code ist gut und wenn Sie 'realloc()' s Dokumentation lesen, können Sie diesen Code ein wenig vereinfachen. Außerdem müssen Sie den Rückgabewert von 'malloc()' oder 'realloc()' nicht umsetzen. –

+0

'oben' sollte ein' int' sein. Oder ändern Sie einfach '% d Elemente' in'% f Elemente', aber ich empfehle das erstere, da es keinen Sinn ergibt, '' über'' ein 'double' zu ​​sein, wenn Ihre Funktion ein' int' zurückgibt. –

+2

In Funktion 'Durchschnitt' wird' i' nicht initialisiert. Güte weiß nur, worauf du zugreifst. –

Antwort

3

So haben andere Antworten bereits darauf hingewiesen, wo das Problem ist und wie genau es behoben werden kann.

printf("%d elements are above average of %lf\n", above, avg); 

Sie übergeben% d als Format Zeichenfolge und dann übergeben Sie ein Doppel.

Dies kann behoben werden, indem Sie oben als int deklarieren (da das ist, was Ihre Funktion auch zurückgibt).

Aber ich möchte hinzufügen, warum es falsch ist und warum erhalten Sie eine Null.

Das ist also das Problem mit Var Args-Funktionen. Da der Prototyp nichts über die Typen der Argumente aussagt, nehmen Sie an, dass printf annimmt, dass das zweite Argument vom Typ double ist.

Nun besagt die Aufrufkonvention, dass das zweite Argument (wenn es float oder double ist) im SSE-Register übergeben werden soll (bei Fenstern im XMM1-Register). Aber da die printf-Funktion sieht, dass die Formatzeichenfolge% d ist, erwartet sie, dass das zweite Argument int ist. Nun werden int-Argumente in den Allzweckregistern übergeben (auf Windows wird zweitens in rdx übergeben).

Als Ergebnis erhält es einen Müllwert.

Ich hoffe, dass dies hilft Ihnen, das Problem besser zu verstehen.

1

1 Wichtige Fehler erneut eingeben müssen.

  • Sie verwenden nie den von realloc() zurückgegebenen Wert

Sie benötigen

ptr = tmp; 

rechts nach Überprüfung, dass realloc() nicht NULL zurückgekommen.

1

Das obige Programm sieht gut aus.

printf ("% d Elemente sind über dem Durchschnitt von% lf \ n", oben, Durchschnitt);

Oberhalb der Zeile drucken Sie einen doppelten Wert mit% d kann falsch sein. Ansonsten sehe ich alles gut.