else ifで多分岐
3つ以上に分けたい
前回の if と else では、2つにしか分けられませんでした。成績は合否だけでなく、A から F までのランクも付けたいところです。分け先が3つ以上あるときは else if をつなげます。
if (score >= 90) {
printf("ランクはAです\n");
} else if (score >= 80) {
printf("ランクはBです\n");
} else if (score >= 70) {
printf("ランクはCです\n");
} else {
printf("ランクはFです\n");
}これは新しい文法ではありません。else のうしろに次の if 文を置いただけです。C の else は「文を1つ」取れるので、そこに if 文が来ています。だから何段でもつなげられます。
上から順に見て、最初に当たった1つだけ
else if の連なりで一番大事な性質は、上から順番に判定して、最初に真になった枝だけを実行し、残りを全部飛ばすことです。
95点のときを追いかけてみます。score >= 90 が真なので A を表示し、そこで終わりです。下にある score >= 80 も score >= 70 も真ですが、評価すらされません。この性質があるおかげで、2つ目以降の条件に「80以上かつ90未満」と書かずに済んでいます。90以上はすでに上で捕まっているので、2つ目にたどり着いた時点で90未満だと分かっているからです。
だから順番を間違えると壊れる
裏を返すと、ゆるい条件を先に書くと後ろが死にます。
if (score >= 60) {
printf("ランクはDです\n");
} else if (score >= 90) {
printf("ランクはAです\n");
}95点でも表示は D です。95 は 60 以上なので1つ目で確定してしまい、A の行には永久に到達しません。条件が数直線で重なるときは、厳しいほうから並べるのが鉄則です。
最後の else を書いておく
一番下の else は「ここまでのどれにも当たらなかった残り全部」を受け止めます。ここを書かずに else if (score >= 0) のように条件を付けると、想定外の値がどの枝にも入らず、何も表示されないプログラムになります。何も起きないバグは原因を追いにくいので、受け皿としての else は必ず用意してください。
else を付けない if を並べるのとは違う
見た目が似ているので、次の書き方と混同しないでください。
if (score >= 90) {
printf("ランクはAです\n");
}
if (score >= 80) {
printf("ランクはBです\n");
}else が無いので、これは独立した2つの if 文です。95点なら A と B の両方が表示されます。1つ目で確定して残りを飛ばす、という働きは else があってはじめて生まれます。ランクのように「必ずどれかひとつ」を選びたいときは、必ず else if でつないでください。
境界をどちらに含めるか
段階評価で必ず問題になるのが境界の値です。80点ちょうどは B なのか C なのかを、先に決めてから書きます。>= は「以上」で境界を含み、> は「より大きい」で境界を含みません。80点を B にしたいなら score >= 80 です。ここを score > 80 にすると80点だけが下の枝に落ち、10段階のうち1点分だけ結果がずれます。テストするときは境界の値そのものを必ず入れて確かめてください。
要件
- まず「点数は95点です」の形で表示する
- 90以上はA、80以上はB、70以上はC、60以上はD、それ未満はFとする
- ランクは「ランクはAです」の形で表示する
- else if をつないで書き、条件は厳しいほうから並べる
入出力例
main("95") → "点数は95点です
ランクはAです"
main("80") → "点数は80点です
ランクはBです"
main("72") → "点数は72点です
ランクはCです"
main("60") → "点数は60点です
ランクはDです"
main("42") → "点数は42点です
ランクはFです"