条件の組み合わせ
判定の軸が2つあるとき
ここまでは点数だけで判定してきました。実際の成績は、点数が足りていても出席が足りなければ不合格になります。判定の軸が2つに増えると、結果は3通りになります。合格、点数不足で不合格、出席不足で不合格の3つです。理由まで表示したいので、単に不合格とまとめるわけにはいきません。
軸が2つあるときの書き方はふたつあります。if の中に if を入れる入れ子と、&& で条件をつなぐ平らな形です。
入れ子で書く
if (attendance >= 80) {
if (score >= 60) {
printf("合格です\n");
} else {
printf("点数不足のため不合格です\n");
}
} else {
printf("出席不足のため不合格です\n");
}外側で出席を見て、出席を満たしている人だけを内側の点数判定へ通しています。内側の else に来た人は「出席は足りているが点数が足りない」人だと確定しているので、理由をそのまま書けます。判定の順序が構造として見えるのが入れ子の利点です。
平らに書く
同じことは && でも書けます。
if (attendance >= 80 && score >= 60) {
printf("合格です\n");
} else if (attendance >= 80) {
printf("点数不足のため不合格です\n");
} else {
printf("出席不足のため不合格です\n");
}字下げが浅く、3つの結果が縦に並ぶので見通しがよくなります。ただし2つ目の枝で attendance >= 80 をもう一度書いている点に注意してください。合格の条件を変えたとき、こちらも直し忘れると矛盾します。
どちらを選ぶか
条件が2つで、片方が明らかな前提条件になっているときは入れ子が読みやすくなります。逆に、結果の一覧を見せたいときや、入れ子が3段以上になりそうなときは平らな形にします。目安として、字下げが3段を超えたら書き方を見直す合図です。
なお && は左から評価され、左が偽と分かった時点で右を見ません。これを短絡評価と呼びます。attendance >= 80 && score >= 60 で出席が足りなければ、点数の比較は行われません。今は結果に影響しませんが、後の章で割り算を条件に入れるときに効いてきます。
else はどの if のものか
入れ子を書くと、else がどの if に対応するのか迷う場面が出てきます。C の決まりは単純で、else は最も近い、まだ else を持っていない if に付きます。
if (attendance >= 80)
if (score >= 60)
printf("合格です\n");
else
printf("出席不足のため不合格です\n");字下げでは外側の if に付けたつもりですが、実際には内側の if に付きます。出席が足りていて点数が足りない人に「出席不足」と表示され、出席が足りない人には何も表示されない、というちぐはぐな結果になります。ここでも効くのが波かっこです。すべての if と else に波かっこを付けておけば、対応が目で見て確定するので、この種の取り違えは起こりません。
要件
- scanf で整数を2つ読む。1つ目が点数、2つ目が出席率
- まず「点数は75点です」の形で表示する
- 出席率が80未満なら「出席不足のため不合格です」と表示する
- 出席率が足りていて点数が60以上なら「合格です」と表示する
- 出席率が足りていて点数が60未満なら「点数不足のため不合格です」と表示する
入出力例
main("75 90") → "点数は75点です
合格です"
main("45 90") → "点数は45点です
点数不足のため不合格です"
main("95 50") → "点数は95点です
出席不足のため不合格です"
main("60 80") → "点数は60点です
合格です"
main(30, 20) → "点数は30点です
出席不足のため不合格です"