• ベストアンサー
※ ChatGPTを利用し、要約された質問です(原文:C言語から質問です。)

C言語で配列の平均値、最大値、最小値を求めるプログラムの作成方法

このQ&Aのポイント
  • C言語で配列の平均値、最大値、最小値を求めるプログラムの作成方法について説明します。
  • まず、main関数の中で初期化した配列を関数keisan()に引数として渡します。
  • 関数keisan()内で配列の要素をループして合計値を求め、同時に最大値と最小値も更新します。最後に平均値、最大値、最小値を配列answerに格納してmain関数に戻します。最後にそれぞれの値を表示することでプログラムは完成します。

質問者が選んだベストアンサー

  • ベストアンサー
noname#144013
noname#144013
回答No.4

こんにちは。 #3です。 以下、#3の補足について。 ■引数 data_kosuu について > 1)データの個数を意味している、、、? >   理解できてません; > 2)データの個数という意味でつかわれている、、。 仰るとおり、引数で渡されている data_kosuu も、関数内で使われている固定値の 10も、共にデータの個数を意味しています。 でしたら、   『固定値の 10 を data_kosuu に置き換えてみる』 ということは考えませんでしたか? 関数 keisan() は、このままだと、要素数10個のデータの計算しか行えません。 関数にするのであれば、要素数が1個であろうが、100個であろうが、要素数に 関係なく計算できるようにした方が汎用的に使用できます。 そのために、要素数を引数として渡すようになっているはずです。 ですので、固定値の10 を使用している箇所を、固定値ではなく可変値に対応 できるように変更する必要があります。 そのために、引数の data_kosuu を使えば良いということです。 ただし、可変値(変数)にするということは、想定外の値(今回の場合は、マイナス 値とか 0 の場合)が渡される可能性もありますので、値のチェックが必要になり ます。 ⇒値のチェックを入れないと、「0割りエラー」などが発生する可能性があります。 さらに、値のチェックなどを入れた場合で、異常判定になった場合は、計算不可 として関数の呼出し元に判定結果を通知してあげる必要があります。 そのために、関数の戻り値を使用します。 ⇒現状では、戻り値が返されていません。 > なんとなくできたみたいですがdata_kosuuを使ってません; > ↓の回答は問題が求めてる回答なんでしょうか? 1)引数の data_kosuu を使用していない点において、仕様を満たしていないかも   しれません。 2)関数 keisan() が戻り値を返していない点において、仕様を満たしていないかも   しれません。 3)配列 data[10]={60,30,70,25,20,9,92,55,20,10} の平均値、最大値,最小値を   計算して(計算結果が正しいことが前提)表示する という点においては、仕様   を満たしていると言えるかもしれません。 ■printf() の書式指定について ※以下は、ちょっと蛇足になります。 少し細かいことになりますが、下記のようにprintf()でdouble型の値の出力を行う 場合の書式指定ですが、   printf("平均=%4.2lf 最小値=%4.2lf 最大値=%4.2lf\n",ans[0],ans[1],ans[2]); この場合の、%4.2lf という記述は、%4.2f のようにサイズ指定子 l を付加しない方 が安全だと思われます。 コンパイラによっては、lf とした場合の動作は未定義になっているので何が起こる かは判りません。 ■参考サイト [迷信] double の出力書式は "%lf" http://www.kijineko.co.jp/tech/superstitions/printf-format-for-double.html 以上です。

drite000
質問者

お礼

data_kosuuに10というのが入ってると思いませんでした、、、。 完全に理解不足ですよね; だからどうやってdata_kosuuに10をいれるのかわからなくて、、、。 なにがともあれ無事完成させるとができました! アドバイスなどありがとうございました!

その他の回答 (3)

noname#144013
noname#144013
回答No.3

こんにちは。 > data_kosuuの使い時がわかりません; これは、#2さんの言われている、   『関数keisanの中で、data_kosuuを使わず    データ数が10だと勝手に決めつけている。』 という意味をよく考えてみて下さい。 1)関数の引数として渡されている data_kosuu は、何を意味しているか   理解されていますか? 2)実際に関数の中で使われている下記部分の固定値の10という値は、   どういう意味で使われているのでしょうか?     for (i=0; i<10 ; i++){      と     sum=sum/10; 上記1)と2)の2つの値の関係をよく考えてみて下さい。 注)除算(割り算)を行う場合、割る数が0だと「0割りエラー」となる場合が   あるので、事前に割る数が0でないかをチェックする必要があります。   割る数が0だった場合、除算は行わずにメッセージを表示するなどの   何らかのエラー対策が必要となります。 > そして一番最初のデータを仮の最大、最小にする方法が思いつきません; これも、#2さんの言われているやり方、   『一番最初のデータを仮の最大値,最小値とする』 これを、そのままプログラムコードに『置き換える』ことを自分なりによく考えて みて下さい。 ヒントは、下記部分の固定値の10を、ある値に『置き換える』ということです。   min=10; /* min の初期化 */   max=10; /* max の初期化 */ ■その他の注意点 1)関数 keisan() の戻り値について   関数 keisan() は、int型の戻り値を返す関数として宣言されていますが、   実際の関数の記述では、戻り値を返している部分がありません。   戻り値の意味合いとしては、おそらく、引数のエラー(範囲オーバーなど)   とか、演算時のエラー(0割り発生など)等をチェックし、処理の正常or異常   の結果を返すことを想定しているものと思われます。   また、main()側での keisan() の呼出しの際は、その戻り値をチェックした   方が良いと思います。 2)関数 keisan() 内の下記の平均値の算出式について     sum=sum/10;   ここで、変数 sum はint型で宣言されていて、固定値10も整数値ですので、   計算結果も整数値(小数点以下が切り捨てられる)になってしまいます。   このままだと、せっかく格納先の変数 answer[0] が、double型なのに、   小数点以下のデータが失われてしまいます。   ※このことは、質問者さんのご提示の文章にも書かれています。 3)main()で使用している下記のprintf()の記述について    printf("平均=%lf 最小値=%d 最大値=%d\n",ans[0],ans[1],ans[2]);   ここで出力しようとしている配列 ans[] は、double型ですが、出力書式の   型は %d の整数型で記述している箇所があり、型が一致していません。   そのため、出力結果が想定外の値で出力される可能性があります。   この場合、書式指定子は %f などの浮動小数点数値に対応したものに   する必要があります。 以上です。

drite000
質問者

補足

>1)関数の引数として渡されている data_kosuu は、何を意味しているか   理解されていますか? >2)実際に関数の中で使われている下記部分の固定値の10という値は、   どういう意味で使われているのでしょうか? 1)データの個数を意味している、、、?   理解できてません; 2)データの個数という意味でつかわれている、、。 関係性はどちらも“データの個数”しか思いつきません; そして 他のアドバイスを考慮していろいろいじってみたら なんとなくできたみたいですがdata_kosuuを使ってません; ↓の回答は問題が求めてる回答なんでしょうか? #include <stdio.h> int keisan(const int data[], int data_kosuu, double answer[]); int main(void) { int i; int a[10]={60,30,70,25,20,9,92,55,20,10}; // この値を使ってください double ans[3]; keisan(a,10,ans); /* keisan関数に配列と配列要素数を引数で与える */ for(i=0; i<10 ; i++) printf("a[%d]=%d\n",i,a[i]); printf("平均=%4.2lf 最小値=%4.2lf 最大値=%4.2lf\n",ans[0],ans[1],ans[2]); return 0; } /* 合計・最大値・最小値を求める関数 */ int keisan(const int data[], int data_kosuu, double answer[]) { int i; double sum; int min,max; min=data[0]; /* min の初期化 */ max=data[0]; /* max の初期化 */ sum=0; /* 合計値の初期化 */ for (i=0; i<10 ; i++){ sum = sum+data[i]; if(data[i] > max) max=data[i]; if(data[i] < min) min=data[i]; } sum=sum/10; answer[0]=sum; answer[1]=min; answer[2]=max; } a[0]=60 a[1]=30 a[2]=70 a[3]=25 a[4]=20 a[5]=9 a[6]=92 a[7]=55 a[8]=20 a[9]=10 平均=39.10 最小値=9.00 最大値=92.00 続行するには何かキーを押してください . . .

  • kmee
  • ベストアンサー率55% (1857/3366)
回答No.2

エラーにあるとおりです。 int keisan( const int data[], /*引数1 */ int data_kosuu,/*引数2 */ double answer[]/*引数3 */ ); とプロトタイプ宣言しているのに keisan( a, /*引数1 */ 10 /*引数2 */ ); と2引数で使おうとしているからです。 他に ・関数keisanの中で、data_kosuuを使わず データ数が10だと勝手に決めつけている。 ・データがすべて10より小さいとき、あるいはすべて10より大きいとき最小/最大が正しくない。 →一番最初のデータを仮の最大値,最小値とするなどの工夫が必要

drite000
質問者

補足

なるほど! 引数の部分は解決しましたが、出力がすごいことになりました。 原因は >・関数keisanの中で、data_kosuuを使わず データ数が10だと勝手に決めつけている。 >・データがすべて10より小さいとき、あるいはすべて10より大きいとき最小/最大が正しくない。 だと思いますが、 data_kosuuの使い時がわかりません; そして一番最初のデータを仮の最大、最小にする方法が思いつきません;

  • SaKaKashi
  • ベストアンサー率24% (755/3136)
回答No.1

>int keisan(const int data[], int data_kosuu, double answer[]) は引数が3つですよね。配列と個数と結果の配列 なのに、呼び出し側は >keisan(a,10); 引数が2つしかありません。 たぶん、 keisan(a,10,ans); でしょ。エラーメッセージに >error C2198: 'keisan' : 呼び出しに対する引数が少なすぎます。 となって、"引数が少なすぎます"って書いてあるじゃないですか。 めっちゃ親切なコンパイラーですね。 もしかして、日本語が読めない?

drite000
質問者

補足

そういうことだったんですか。 解説ありがとうございます。