2012-05-03 48 views
0

私はいくつかのfloatの平均を計算するためにこの関数を書いています。しかし、「平均」関数の最後の行にランタイムエラーがあります。問題は何ですか?可変引数を持つ関数ランタイムエラー

#include <stdarg.h> 
#include <stdio.h> 



float average(float first , ...) 
{ 
    int count = 0; 
    float sum = 0 , i = first; 

    va_list marker; 

    va_start(marker , first); 
    while(i != -1) 
    { 
     sum += i; 
     count++; 
     i = va_arg(marker , float); 
    } 

    va_end(marker); 
    return(sum ? (sum/count) : 0); 
} 


int main(int argc , char* argv[]) 
{ 
    float avg = average(12.0f , 34.0f); 

    printf("The average is : %f\n" , avg); 
    scanf("a\n"); 
} 
+1

私は、さまざまな引数を持つ関数が、価値があるよりも多くの問題を引き起こすことを発見しました。特に、C++を使用する場合、これを回避する方法がより優れています。 –

+1

特にセンチネルとして '-1'を使うのは本当に悪いデザインですが、これは有効な値かもしれません。あなたのすべてのパラメータは同じ型であるはずなので、C++だけでなくCもこれに代わるより良い選択肢を提供します。 –

答えて

2

あなたは-1との通話を終了するのを忘れたので、それはあなたが渡されたよりも多くの引数を取得し維持しようとするので、あなたのwhileループは未定義の動作が発生します。可変長引数の関数に渡されるとき

float avg = average(12.0f, 34.0f, -1f); 

また、float引数はdoubleに昇格されているので、あなたはva_argfloatを使用することはできません:それはする必要があります。それは-1を見るまで

double average(double first, ...) 
{ 
    int count = 0; 
    double sum = 0, i = first; 

    va_list marker; 

    va_start(marker, first); 
    while(i != -1) 
    { 
     sum += i; 
     count++; 
     i = va_arg(marker, double); 
    } 

    va_end(marker); 

    return sum ? sum/count : 0; 
} 

double avg = average(12.0, 34.0, -1.0); 
+0

それは成功しました。しかし、とにかく、渡された議論で-1を使用しないのですか? –

+1

@ Arman-aegit関数は、いつ引数を抽出するのをいつ止めるべきか(つまり、whileループをいつ止めるべきか)を知る必要があります。だから、あなたが今やっているように、最後に価値を与えるか、合計したい引数の数を与える最初の引数を追加するかのようにしなければなりません。だから、 'double average(int count、...)'のようになり、 'double avg = average(3,1.0,2.0,3.0) 'を実行できます。残念ながら、渡された引数の数を自動的に知る方法はありません。 –

4

機能はループ、呼び出し側は-1を供給されていません:あなたは、すべてこのためにdoubleを使用する必要があります。

私のボックスのmanページをお約束し、 "ランダムエラー":

va_arg() 
    ... 
    If there is no next argument, or if type is not compatible with the 
    type of the actual next argument (as promoted according to the default 
    argument promotions), random errors will occur. 

試してみてください。

float avg = average(12.0f, 34.0f, -1f); 
2

あなたが渡す-1への最後の引数として必要はありませんwhileループを停止しますか?

はまた、私はこの問題は、あなたのwhileループのために終了していないということです

2

...山車がのVAを使用した場合、その倍にするフロートを変更すると良いでしょうダブルスに変換されていると信じています。 -1を確認していますが、決して-1を渡しません。あなたは

float avg = average(12.0f ,34.0f, -1); 

ほぼ正確にあなたのコードを示しva_arg, va_end, va_startで、この例の実行時の例があるとして、あなたのaverage関数を呼び出す必要がありますが、値のためint代わりのfloatを使用します。

関連する問題