2017-03-21 22 views
1

私はクラス用のプログラムを作成しましたが、問題があります。プログラムの目的は、値のセットを配列に読み込み、平均を計算し、その配列内のいくつの要素がその平均よりも大きいかを調べることです。関数のプロトタイプは変更できないように提供されています。また、配列のサイズを10に初期化し、読み込み要素の数が現在のサイズを超えるたびにサイズを2倍にするように指示されたため、変更することはできません。

私が実行している問題は、上記の平均関数からの値を返すことです。返り値の前に表示するprintfを置くことができますが、main関数で返される値は0です。

また、コメントprintfのラインが関数によって返される値をチェックすることでした。私の代わりにそれを削除するので、私はそれを毎回再入力する必要はありません、それをコメントアウト。C関数が値を返さない

#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

これはあなたの問題を助けるものではありませんが、あなたのコードは良いですし、 'realloc()'のドキュメントを読むと、このコードを少し簡略化することができます。また、 'malloc()'や 'realloc()'の戻り値をキャストする必要もありません。 –

+0

'above'は' int'でなければなりません。あるいは単に%d個の要素を%f個の要素に変更するだけですが、関数が 'int'を返すときに' above'がなぜ 'double'なのか理解できないので、前者をお勧めします。 –

+2

関数 'average'では、' i'は初期化されません。善良さはあなたがアクセスしているものだけを知っています。 –

答えて

3

他の回答から、既に問題がどこでどのように解決されているのかが既に指摘されています。

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

フォーマット文字列として%dを渡してから、doubleを渡します。

これは、上記のようにintで宣言することで修正できます(これも関数から返されます)。

しかし、なぜそれが間違っているのか、なぜゼロになっているのかを追加したいと思います。

これはvar args関数の問題です。プロトタイプは引数の型について何も言わないので、printfを呼び出すと、2番目の引数がdouble型であるとみなされます。

呼び出し規約では、2番目の引数(floatまたはdoubleの場合)をSSEレジスタ(XMM1レジスタのウィンドウ)に渡す必要があることが示されています。 printf関数はフォーマット文字列が%dなので、2番目の引数がintであることを期待しています。現在、int引数は汎用レジスタに渡されます(2番目のウィンドウはrdxで渡されます)。

結果として、ガベージ値を取得します。

私はこれが問題の理解に役立つことを願っています。

1

1重要間違い

  • realloc()が返す値は決して使用しないでください。

あなたは正しいrealloc()NULLを返さなかったことを確認した後

ptr = tmp; 

を必要としています。

1

上記のプログラムは正常です。

printf( "%d個の要素は%lfの平均以上です\ n"、上記、平均);

%dの倍数を印刷している行は間違っている可能性があります。そうでなければ、私はすべてうまくいくと思う