
「キーボードから10個の実数を入力し、それらの平均を求めるプログラムを作れ。」という問題で私は、
#include <stdio.h>
void main(void)
{
float A;
float a,b,c,d,e,f,g,h,i,j;
printf("実数を入力してください:");
scanf("%f",&a);
scanf("%f",&b);
scanf("%f",&c);
scanf("%f",&d);
scanf("%f",&e);
scanf("%f",&f);
scanf("%f",&g);
scanf("%f",&h);
scanf("%f",&i);
scanf("%f",&j);
A=(a+b+c+d+e+f+g+h+i+j)/10;
printf("平均は%fです.\n",A);
}
と考えたのですが、もっとすっきりとしたプログラムはないのでしょうか?もっとシンプルにしたいのです。教えて下さい。よろしくお願いします。
No.2ベストアンサー
- 回答日時:
同じ処理の繰り返しなのだから、
最低限必要な処理を考えて繰り返し文を使うと良いです
void main(void)
{
float sum = 0;
float data;
int i;
for (i = 0;i < 10;i++){
printf("実数を入力してください:(%d/10)",i+1);
scanf("%f",&data);
sum+=data;
}
sum /= 10
printf("平均は%fです.\n",sum);
}
こんな感じでいかがでしょう
No.3
- 回答日時:
※長いので、お暇な時にでも読んでください(^^;
※最終的なソースは、1番下にあります。
■1■変数の数を減らすことから始めよう
今10個の値を入力するために、a~jの10個の変数を宣言していますが、もしこれが100個の値を入力する問題だったらどうしましょう?
同じ用途の変数がたくさん必要な場合には、配列変数を使うと便利です。配列とは「1つの変数にたくさんの値を入れられるようにしたもの」です。配列の宣言は次のようにします。
データ型 配列変数名[使う個数];
例えばこの問題では、「 float a[10]; 」と宣言すれば、aの0番目( a[0] )から、aの9番目( a[9] )までが使えるようになります。(この a[0] ~ a[9] を、配列aの「要素」といいます。)
宣言では[ ]内に使う個数を書き、使う時は0からの通し番号を入れるわけです。0から数えるので、a[10]は使えないことに注意してください。
配列を使うと、次のように書き換えることが出来ます。(main関数内のみ)
float A, a[10];
printf("実数を入力してください:");
scanf("%f",&a[0]);
scanf("%f",&a[1]);
scanf("%f",&a[2]);
scanf("%f",&a[3]);
scanf("%f",&a[4]);
scanf("%f",&a[5]);
scanf("%f",&a[6]);
scanf("%f",&a[7]);
scanf("%f",&a[8]);
scanf("%f",&a[9]);
A=(a[0]+a[1]+a[2]+a[3]+a[4]+a[5]+a[6]+a[7]+a[8]+a[9])/10;
printf("平均は%fです.\n",A);
■2■配列の各要素を、変数で使い分けよう
上記プログラムは、全然すっきりなんてしていませんね。結局100個の値が必要ななったら、えらい手間がかかってしまいます。
配列を使う一番のメリットは、各要素を変数で使い分けることができる点です。つまり、a[0] の代わりに、b = 0; a[b] と書くことができるのです。この変数bを、forループを使って1ずつ増やしてやれば、たとえ100個の値が必要になっても問題ないわけです。
これを使って、前半部分は次のように書き換えられます。
int i; /* forループでは i を使うのが習慣です。 */
float A, a[10];
printf("実数を入力してください:");
for (i = 0; i <= 9; i++) {
scanf("%f",&a[i]);
}
※forループの使い方が分からなければ質問してください。
■3■少しずつ計算しよう
次に合計を求めて個数で割る部分についてですが、足し算を全部書いたらすごく大変ですよね?
ここでは「足し込み」という、ちょっとしたテクニックを使って、プログラムを簡単にします。
まず次のプログラムは理解できますか?
int a = 1; printf("a=%d\n", a); /* 当たり前ですが「a=1」ですね */
a = a + 2; printf("a=%d\n", a); /* a + 2 が計算されて、a に代入されているので「a=3」です */
この「ある変数に数を足した結果を、その変数にする」というのが「足し込み」です。普通は「 a = a + 2; 」ではなく、「 a += 2; 」のように省略形を使って書きます。
この手法を用いて、a[0] ~ a[9] を、A に足し込みます。前もって A の値を 0 にしておけば、a[0] ~ a[9] の合計が求まるわけです。
それではループ・足し込みを使って、後半部分を書き換えてみます。
A = 0.0;
for (i = 0; i <= 9; i++) {
A += a[i];
}
A = A / 10;
printf("平均は%fです.\n",A);
■4■同じループができちゃった
前半と後半のプログラムを見比べてみると、全く同じ形の for文 がありますよね。前半では10回分の入力を、後半では10回分の足し算を行っているわけです。
ここでちょっと考えてみてください。
ここまででは「全部入力した後、全部計算する」という形になっているわけですが、「1個入力したら、1個足し込む」をループさせても、うまくいくような気がしませんか?
実際にくっつけてみると、下記のようなソースになります。
int i;
float A, a[10];
printf("実数を入力してください:");
A = 0.0; /* 後半ループの前に行う必要があったので、くっつけたループの上に持ってきます */
for (i = 0; i <= 9; i++) {
scanf("%f",&a[i]);
A += a[i];
}
A = A / 10;
printf("平均は%fです.\n",A);
だいぶすっきりしましたよね?
■5■入力した1つ1つの値って、後で使いますか?
配列を使って10個分の入力をしたわけですが、おかげで「何番目に何を入力したか」がいつでも分かって便利ですね。何せ a[ 何番目 ] と書くだけですから。(0番目から数えます。)
ところで、この「1つ1つの入力した値」って、何かに使いますか?もし使わないのなら、全部取っておく必要ないですよね?
そもそも配列にした理由は、「たくさんの入力を行うのに、別々の変数を用意するのが大変だったから」です。
今はループを使って、「1個入力したら1個足し込み」にしているので、実は変数は1個でも構わないんです。だって入力した値を A に足し込んじゃえば、入力した値はもうどうでも良いわけで、その変数を何に使おうが問題ないわけですから。
では、a[x] と書かれた部分を、a にしちゃいましょう。宣言とループ内の3箇所を直せばいいですね。
■6■掛け持ち変数は、バグの元!
ところで変数 A って、何用の変数ですか?合計を求めるのに使って、その後平均を求めて・・・
まぁ今回はその程度だから問題はあまり無いんですが、1つの変数を用途を限定せずにあちこちで使いまわすと、思わぬバグを引き起こすことがあります。
ですので、合計用と平均用で変数を分けておきましょう。
その際、用途が分かるような名前を付けたほうが、後で見た時&他の人が見た時に、理解しやすいコードになります。コメントをつけるのも良いことなのですが、変数1つ1つに、しかも出てくるトコ全部に書くわけにいかないでしょ?
合計には sum または goukei 、平均には ave または heikin 等がよいでしょうね。
■7■マジックナンバーをなくそう
「マジックナンバー」とは、プログラム中に出てくる意味不明な数字のことです。
ここでは forループで使ってる 9 と、平均を求める際の 10 で、両方とも「10個のデータ」という問題絡みのものです。
何が問題かというと、例えば問題を「50個の入力値の平均を求めるプログラム」に変えられた時、ぱっと見てどこを直せばよいかが分かりにくく、修正漏れによるバグを起こしやすいことです。
このプログラムの場合、処理するデータの個数を「グローバル変数」や「マクロ」なりに置き換えて、修正個所を1つにしてしまいましょう。ただの「数字」が、変数などの「名前」になることで、プログラムも分かりやすいものになります。
※グローバル変数やマクロについて分からなければ質問してください。
■8■最終的なソース
#include <stdio.h>
int data_num = 10; /* データの個数を変更する時は、ここを直せばOK */
void main( void )
{
int i;
float sum, ave, a;
printf("実数を入力してください:");
sum = 0.0;
for (i = 0; i <= data_num-1; i++) {
scanf("%f",&a);
sum += a;
}
ave = sum / data_num;
printf("平均は%fです.\n", ave);
}
それでは頑張って勉強してくださいね
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
似たような質問が見つかりました
- C言語・C++・C# 至急教えてください!プログラミングの問題です。 割られる整数と割る整数を受け取って、商と余りを出力す 3 2022/07/05 10:23
- C言語・C++・C# C言語(構造体) 3 2022/07/05 20:08
- C言語・C++・C# 宣言する関数の形が決まっている状態で、 str1とstr2の文字列をこの順に引っ付けてstrに保存し 2 2022/05/30 18:21
- C言語・C++・C# c言語でユーザ関数を利用して複素数のべき乗と絶対値の数列を計算するプログラムが作りたいです。 3 2023/01/29 22:13
- C言語・C++・C# C言語プログラム変更 2 2022/12/21 15:03
- C言語・C++・C# c言語配列の結合についてです。 なぜうまくいかないのでしょうか。 #include <stdio.h 4 2022/05/30 22:42
- C言語・C++・C# C言語でif文が予想と違う動きをする件について7 4 2023/03/20 00:26
- C言語・C++・C# C言語 3 2022/10/04 15:07
- C言語・C++・C# C言語 プログラミング 4 2022/05/22 11:53
- C言語・C++・C# c言語の問題です 3 2023/01/10 16:15
このQ&Aを見た人はこんなQ&Aも見ています
関連するカテゴリからQ&Aを探す
おすすめ情報
このQ&Aを見た人がよく見るQ&A
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
Eclipseコンソール表示を、リセ...
-
数字以外が入力されたらエラー...
-
java初心者です。入力されたの...
-
scanfが2回使えない・・・?;
-
C言語・YesNo入力のループで解...
-
正負を反転させて出力するプロ...
-
getchar()について 教えてくだ...
-
"scanf"でエンターで改行させな...
-
コマンドプロンプトからのEOFの...
-
至急教えてください!プログラ...
-
*をユーザーが入力した数字の数...
-
scanf関数 バッファに残ったエ...
-
入力候補を表示させるには・・・?
-
EDITコントロールで入力できる...
-
Excel VBAで、Application.Inpu...
-
入力値が1以下、かつ数字以外の...
-
WindowsでEOF
-
電卓の小数点
-
getcharをしながらwhile文で出...
-
ワードで文字を入力する時の変...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
正負を反転させて出力するプロ...
-
プログラミング初心者です。 Py...
-
数字以外が入力されたらエラー...
-
Excel VBAで、Application.Inpu...
-
EDITコントロールで入力できる...
-
*をユーザーが入力した数字の数...
-
Linuxプログラミングで、キーボ...
-
Eclipseコンソール表示を、リセ...
-
入力候補を表示させるには・・・?
-
batプログラム上で文字列を入力...
-
UWSCで変数をキー入力
-
VisualStudio2019のコードアナ...
-
小数か整数かを判定する方法
-
scanfが2回使えない・・・?;
-
Linuxで入力待ちなしkeyread関...
-
java初心者です。入力されたの...
-
Delphi初心者 ボタン操作につ...
-
コマンドプロンプトからのEOFの...
-
Eclipseでコマンドラインを入力...
-
Userformの入力順序をタブオー...
おすすめ情報