つくる 合否とランク判定
前回作った平均表示の続きから
第2章の最後で、3科目の点数を読み込んで合計と平均を表示するところまで作りました。今回はその続きとして、平均から合否とランクを出すところまで仕上げます。入力と計算の部分はそのまま使えるので、書き足すのは判定だけです。
第2章のプログラムはこうなっていました。
int total = kokugo + suugaku + eigo;
double average = (double)total / 3;
printf("国語%6d点\n", kokugo);
printf("数学%6d点\n", suugaku);
printf("英語%6d点\n", eigo);
printf("合計%6d点\n", total);
printf("平均%6.1f点\n", average);%6d は「6桁分の幅を取って右に寄せる」書式で、これのおかげで点数の桁がそろって見えます。(double) のキャストを忘れると、整数どうしの割り算になって小数が切り捨てられます。255 を 3 で割ると 85 なので気づきませんが、250 を 3 で割ると 83.3 が 83 になります。ここは第2章でつまずいたところなので、書き写すときにも落とさないでください。
判定を足す
ここから先が今回の内容です。平均を使って、ランクと合否の2行を追加します。
ランクは範囲の判定なので else if を厳しいほうから並べます。合否は2つに分かれるだけなので if と else で十分です。判定の軸が違うので、ひとつの連なりに混ぜず、別々に書きます。ランクの連なりに合否を紛れ込ませると、A なら合格とだけ書いた枝ができ、あとで基準を変えるときに直し漏れが出ます。
小数を条件に使うときの注意
今回は double の average を >= で比較します。> や >= は安全ですが、小数どうしを == で比べるのは避けてください。コンピュータは小数を2進数の近似で持っているので、計算の途中で目に見えないずれが生まれ、average == 60.0 が成り立たないことがあります。等しいかどうかを判定したいときは、整数で比べられる形に持ち込むのが定石です。
表示の桁にも気をつけます。%f をそのまま使うと 85.000000 と小数点以下が6桁出ます。%.1f と書いて1桁に丸めます。これは表示だけの丸めで、average が持っている値そのものは変わりません。表示が 60.0 に見えても、内部の値がわずかに 60 を下回っていれば判定は不合格になります。表示と判定は別物だと覚えておいてください。
ランクと合否を混ぜない
ここまでの部品をひとつの else if の連なりにまとめたくなるかもしれません。
if (average >= 90) {
printf("ランクはAです\n");
printf("判定は合格です\n");
} else if (average >= 80) {
printf("ランクはBです\n");
printf("判定は合格です\n");
}これでも同じ表示になりますが、合格の基準を70点に変えたくなったとき、直す場所が枝の数だけ散らばります。判定の軸が違うものは、別の if として並べておくのが安全です。今回のプログラムは、入力、計算、一覧の表示、ランクの判定、合否の判定、という5つのかたまりが上から順に並ぶ形になります。この並びは、第4章で人数分の繰り返しを足すときにもそのまま活きます。
動かして確かめる
書き終えたら、境界の値を入れて動かしてください。平均がちょうど60になる入力、ちょうど90になる入力を試すと、>= と > の取り違えがすぐ見つかります。
要件
- scanf で国語、数学、英語の順に整数を3つ読む
- 第2章と同じく、バナー、各科目、合計、平均を表示する
- 平均が90以上はA、80以上はB、70以上はC、60以上はD、それ未満はFとし、「ランクはBです」の形で表示する
- 平均が60以上なら「判定は合格です」、そうでなければ「判定は不合格です」と表示する
- ランクの判定と合否の判定は、別々の if として並べて書く
入出力例
main("78 92 64") → "=== 成績管理 ===
国語 78点
数学 92点
英語 64点
合計 234点
平均 78.0点
ランクはCです
判定は合格です"
main("90 85 80") → "=== 成績管理 ===
国語 90点
数学 85点
英語 80点
合計 255点
平均 85.0点
ランクはBです
判定は合格です"
main("100 95 90") → "=== 成績管理 ===
国語 100点
数学 95点
英語 90点
合計 285点
平均 95.0点
ランクはAです
判定は合格です"
main("70 65 60") → "=== 成績管理 ===
国語 70点
数学 65点
英語 60点
合計 195点
平均 65.0点
ランクはDです
判定は合格です"
main(50, 40, 30) → "=== 成績管理 ===
国語 50点
数学 40点
英語 30点
合計 120点
平均 40.0点
ランクはFです
判定は不合格です"