重要課題 11..1
要素数が指定された1次元配列内の各要素の平均値を出力するプログラムを、引数 として指定された配列とその要素数から平均値を計算する関数
double average(int array[/url], int size)
を用いて作れ。配列の各要素は整数とし、配列の要素数の最大数は512とする。
% ./arrayAverage
input size: 4
input u[0]: 9
input u[1]: 20
input u[2]: 4
input u[3]: 11
average is 11.000000
%
という課題がわかりません。
自分が書いたソースがこれです。
/* ここからコピー */
#include <stdio.h>
# define BUFFER_SIZE (256)
int get_int(void)
{
char buf[BUFFER_SIZE];
fgets(buf, BUFFER_SIZE, stdin);
return atoi(buf);
}
/* ここまでコピー */
//平均を
double average(int aray[/url],int size)
{
int i;
int b;
double result;
b=0;
for(i=0;i<size;i++)
{
b += aray;
}
result = b / size;
return result;
}
int main()
{
//出力
int p[512],number,suuzi;
printf("input size:");
number = get_int();
for(suuzi=0;suuzi<number;suuzi++)
{
printf("input u[%d]:",suuzi);
p[suuzi] = get_int();
}
printf ("average is %f \n",average(p,number));
return 0;
}
//ここまで
これをコンパイルすると正しい平均値になりません。何がまちがっているのでしょうか?
配列の関数への引渡し
Re:配列の関数への引渡し
>result = b / size;
int型同士の割り算の結果はint型になるので、小数部が切り捨てられてしまいます。
result = (double)b / size;
のようにキャストすることで正しい平均値を求められると思います。
int型同士の割り算の結果はint型になるので、小数部が切り捨てられてしまいます。
result = (double)b / size;
のようにキャストすることで正しい平均値を求められると思います。
Re:配列の関数への引渡し
整数徐算の問題以外に、オーバーフローを回避する必要もあると思います。
処理系不明なのではっきりしたことはいえませんが、累算結果を格納する変数はintmax_t型にするなどの工夫が必要です。
徐算の際も、double型ではなく、long double型にしておいたほうが無難かと思います。
処理系不明なのではっきりしたことはいえませんが、累算結果を格納する変数はintmax_t型にするなどの工夫が必要です。
徐算の際も、double型ではなく、long double型にしておいたほうが無難かと思います。
Re:配列の関数への引渡し
すいません。貼るソースを間違えました。
#include<stdio.h>
# define BUFFER_SIZE (256)
int get_int(void)
{
char buf[BUFFER_SIZE];
fgets(buf, BUFFER_SIZE, stdin);
return atoi(buf);
}
//プロトタイプ宣言
double average(int array[/url],int size);
//main関数
int main(void){
//サイズと各配置の入力
int array[512];
int number,i;
printf("input size : ");
number=get_int();
for(i=0 ; i<number ; i++){
printf("input u[%d] : ",i);
array = get_int();
}
//average関数の呼出
printf("average is %f\n",average(array,number));
return 0;
}
//average関数
double average(int array[/url],int size){
//平均を計算する
int i,sum;
double ans;
for(i=0; i<size ; i++){
sum += array;
}
ans =(double)sum/size;
return ans;
}
このソースでコンパイルして実効ファイルを実行して、全部3で入力するとaverage is -358346330.333333と表示されます。なぜでしょうか?
#include<stdio.h>
# define BUFFER_SIZE (256)
int get_int(void)
{
char buf[BUFFER_SIZE];
fgets(buf, BUFFER_SIZE, stdin);
return atoi(buf);
}
//プロトタイプ宣言
double average(int array[/url],int size);
//main関数
int main(void){
//サイズと各配置の入力
int array[512];
int number,i;
printf("input size : ");
number=get_int();
for(i=0 ; i<number ; i++){
printf("input u[%d] : ",i);
array = get_int();
}
//average関数の呼出
printf("average is %f\n",average(array,number));
return 0;
}
//average関数
double average(int array[/url],int size){
//平均を計算する
int i,sum;
double ans;
for(i=0; i<size ; i++){
sum += array;
}
ans =(double)sum/size;
return ans;
}
このソースでコンパイルして実効ファイルを実行して、全部3で入力するとaverage is -358346330.333333と表示されます。なぜでしょうか?
Re:配列の関数への引渡し
Study Cで起動したら(初期化は無視しました。ちょっとしたことは無視してくれる)
3.000000と出ました。(すべて3と入力)
ソースのせいではないのでは?
メモリ不足とか…は、ないですよね。
ちょっとした事のせいですかね…初期化してないとかの…
3.000000と出ました。(すべて3と入力)
ソースのせいではないのでは?
メモリ不足とか…は、ないですよね。
ちょっとした事のせいですかね…初期化してないとかの…
Re:配列の関数への引渡し
アビゲイルさんもおっしゃってますが、sumが初期化されていません。
初期化されていない自動変数の読みだしを行った場合の動作は未定義です。
つまり、sum += array; を実行した結果、何事も無かったかのようにsumの値が0で初期化されているかのように振る舞うかもしれませんし、エラーを吐いて落ちるかもしれませんし、常に0を代入するかもしれませんし、アーキテクチャがそれを許すならば、鼻から悪魔が出てくるかもしれません。
初期化されていない自動変数の読みだしを行った場合の動作は未定義です。
つまり、sum += array; を実行した結果、何事も無かったかのようにsumの値が0で初期化されているかのように振る舞うかもしれませんし、エラーを吐いて落ちるかもしれませんし、常に0を代入するかもしれませんし、アーキテクチャがそれを許すならば、鼻から悪魔が出てくるかもしれません。