つくる N人分の入力

3人固定から、N人へ

第2章のつくる回では、3 科目ぶんの点数を入力して平均を出しました。あのプログラムは scanf を 3 回並べて書いていたので、4 人になった瞬間に書き直しが必要でした。この章でループを覚えたので、いよいよ 人数を実行時に決められる 形にします。

組み立ては 3 つの部品でできています。

  • 人数を 1 回だけ読む
  • その回数だけループを回し、中で 1 人ぶんの点数を読んで合計に足す
  • ループを抜けてから、合計と平均を出す

変数はループの外に置く

いちばん間違えやすいのが、合計を入れる変数の置き場所です。

int total = 0; for (i = 1; i <= n; i++) { scanf("%d", &score); total += score; }

total は全員ぶんを積み上げる箱なので、ループの で 1 回だけ 0 にします。ループの中で int total = 0; と書くと、毎回作り直されて 0 に戻り、最後の 1 人ぶんしか残りません。一方 score は 1 人ぶんの一時的な値なので、毎回上書きされてかまいません。この「積み上げる変数」と「使い捨ての変数」の区別は、次章以降もずっと出てきます。

人数ぶんの点数を保管しておく方法はまだ習っていないので、読んだ点数はその場で合計に足して捨てます。全員の点数をあとから見返せるようにするのは、第6章の配列の仕事です。

平均で切り捨てないために

第2章で見たとおり、int どうしの割り算は小数が切り捨てられます。240 を 3 で割ると 80 ですが、250 を 3 で割ると 83 になり、正しい 83.33 が消えます。

double average = (double)total / n; printf("平均は%.1f点です\n", average);

片方を double にキャストすれば、割り算そのものが小数の計算になります。表示のときは %f のままだと小数第 6 位まで出てしまうので、%.1f と桁を指定します。

入力を促すメッセージも忘れずに出してください。何も表示せずに入力待ちになるプログラムは、使う人から見ると固まったのと区別が付きません。今回は「1人目の点数」のように何人目かを添えるので、printf の中でループ変数 i をそのまま使えます。

この章でできるようになったこと

第3章までのプログラムは、書いた時点で処理の回数が決まっていました。この章のループを手に入れたことで、実行してみるまで分からない量のデータを扱えるようになりました。人数が 3 人でも 40 人でも、コードは 1 文字も変わりません。これは繰り返しがもたらす、いちばん大きな変化です。

残っている弱点は、読んだ点数をその場で捨てていることです。合計は出せても、あとから「2 人目は何点だったか」を聞かれると答えられませんし、最高点を探すこともできません。値をまとめて持っておく道具が配列で、第6章で扱います。次章ではその前に、長くなってきた main を切り分けるための関数を学びます。

では、人数を聞いて、その人数ぶんの点数を集計する成績管理CLI を書きましょう。

要件

  1. 最初に「人数を入力してください」と表示して人数を読む
  2. 点数を読む前に「1人目の点数」の形で何人目かを表示する
  3. 合計は「合計は240点です」の形で表示する
  4. 平均は「平均は80.0点です」の形で、小数第1位まで表示する
  5. 人数は1以上が入力される前提でよい

入出力例

main(3, 80, 90, 70) → "人数を入力してください 1人目の点数 2人目の点数 3人目の点数 合計は240点です 平均は80.0点です" main(4, 100, 85, 60, 55) → "人数を入力してください 1人目の点数 2人目の点数 3人目の点数 4人目の点数 合計は300点です 平均は75.0点です" main(3, 80, 85, 85) → "人数を入力してください 1人目の点数 2人目の点数 3人目の点数 合計は250点です 平均は83.3点です"

ヒント

生田 陸人
ゆめさくエンジニア / 現役ソフトウェアエンジニア
編集 LuaGate編集部
main.c
学習モード

メモ

つくる N人分の入力

⌘S で保存