想定外の動作を引き起こすフォールスルーとは、一体何なのでしょうか…?
switch文を使っているんだけど、なんか動作がおかしい…
たくさんの条件分岐をシンプルなコードで表現できるswitch文ですが…
想定外の変な動きをしたことはありませんか…?
気になるところへGO!
switch文の動作異常の原因であるフォールスルーとは…?

switch文を使ったときに、当てはまらない条件の処理が実行されてしまうことがあります。
この現象はフォールスルーと呼ばれるもので、この現象の大半はbreakのつけ忘れが原因です。
switch文をご紹介したときに、『caseの処理の最後にはbreak;を付ける』というルールをご紹介しました。
実はこのルールに反して『break』を書き忘れてしまうと、他のcaseの処理も実行されてしまうんです。
さっそく、具体例を見てみましょう。
// 入力値が『1 or 2 or それ以外』であることを判別する
#include<stdio.h>
int main(void) {
int num;
printf("1か2を入力してください→\n");
scanf("%d", &num);
switch (num) {
case 1:
printf("One\n");
// break;
case 2:
printf("Two\n");
break;
default:
printf("クソが!\n");
break;
}
return 0;
}
このプログラムは入力された数値が『1』or『2』or『それ以外』であることを判別するプログラムです。
解説用にcase 1の『break;』の行をコメントアウトしています。
さっそく実行して『1』を入力してみましょう。
switch文でbreakをつけ忘れると、当てはまっていない条件のcaseの処理まで実行されてしまいます。
これがフォールスルーという現象です。
試しに、case1のbreakの先頭にある『//』を削除して、もう一度実行してみてください。
きちんとswitch文が動作することが確認できると思います。
意外と知られていないswitchの本当の能力

意外と知られていないのですが、switch文の能力は『条件に当てはまるcaseの処理を実行する』というものではありません。
switch文の本当の能力は『当てはまったcase以降のすべての処理を実行する』というものなんです!
先程のプログラムの動作を思い出してください。
『1』を入力したときはcase1の条件に当てはまるので、『One』が表示されたと思います。
ここに『break;』があればswitch文は正常終了するのですが、書き忘れるとswitch文の本当の能力が発動してしまうんです。
つまり、case2の処理も実行されて『Two』も表示されてしまいます。
このようにswitch文の本当の能力は『当てはまったcase以降のすべての処理を実行する』というものになります。
しかし、このままだと使いづらいので、『break』を書いてelse ifのような条件分岐として使っていたということなんですね。
breakを忘れると余計な処理まで実行してしまうので、switch文を使うときはbreakを忘れないように気を付けましょう!
フォールスルーが許される唯一の方法

switchのフォールスルーは原則禁止ですが、使ってもいい場面が1つだけあります。
それは、複数のcaseをまとめるときです。
次のプログラムをご覧ください。
// 1~4の奇数・偶数を判別する
#include<stdio.h>
int main(void) {
int num;
printf("1〜4の数値を入力してください→");
scanf("%d", &num);
switch (num) {
case 1:
case 3:
printf("奇数です\n");
break;
case 2:
case 4:
printf("偶数です\n");
break;
default:
printf("もう知らない!\n");
break;
}
return 0;
}
これは入力された1〜4の奇数・偶数の判定を行うプログラムです。
このプログラムの場合、『1と3』『2と4』が表示する文字が同じになるのは、すでにお気づきでしょう。
しかし、同じコードを2回書くことは、保守性の観点から好ましくありませんし面倒です。
そんなときに役に立つのが、フォールスルーになります。
同じ処理を行う条件が複数あるときには、breakを挟まずにcaseを連続して書いてしまいます。
そうすることで処理の内容が同じ条件をひとまとめにすることができるんです。
結論から言ってしまうと、先程のプログラムの場合はnumが1でも3でも『奇数』と表示されます。
というのも、switch文は条件に当てはまったcase以降のすべての処理を実行するからです。
そのため、case1に該当したらcase3に当てはまるかどうかは関係ありませんし。
case1に該当しなくても、case3に当てはまれば『奇数』と表示する処理が実行されます。
そして、きちんと処理の部分にbreakを書いておけば、問題なくswitch文を終了させることができるんです。
まとめ
以上がswitch文の動作異常を引き起こすフォールスルーとswitch文の本当の能力になります。
想定外の動作を引き起こすフォールスルーはかなり危険なので、breakのつけ忘れに注意しましょう。
