30代から始めるC言語

【C言語・switch文の注意点】breakをつけ忘れると起きるフォールスルーとは…?

トビタカ
トビタカ
本記事ではswitch文を使ったときに発生するフォールスルーに関して解説しています。

想定外の動作を引き起こすフォールスルーとは、一体何なのでしょうか…?

 

switch文を使っているんだけど、なんか動作がおかしい…

 

たくさんの条件分岐をシンプルなコードで表現できるswitch文ですが…

想定外の変な動きをしたことはありませんか…?

とび助
とび助
なんか、当てはまらないはずのcaseの処理が実行されたことがあります…
トビタカ
トビタカ
それはフォールスルーという現象の可能性が高いですね!

switch文の動作異常の原因であるフォールスルーとは…?

switch文を使ったときに、当てはまらない条件の処理が実行されてしまうことがあります。

この現象はフォールスルーと呼ばれるもので、この現象の大半はbreakのつけ忘れが原因です。

トビタカ
トビタカ
当てはまったcaseの処理に『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』を入力してみましょう。

とび助
とび助
あれ、『Two』も表示されてしまいました。
トビタカ
トビタカ
それがフォールスルーという現象ですよ!

 

switch文でbreakをつけ忘れると、当てはまっていない条件のcaseの処理まで実行されてしまいます。

これがフォールスルーという現象です。

試しに、case1のbreakの先頭にある『//』を削除して、もう一度実行してみてください。

きちんとswitch文が動作することが確認できると思います。

とび助
とび助
本当だ!きちんと動きました!
トビタカ
トビタカ
他のcaseの処理が実行されたらbreakのつけ忘れを確認してくださいね。

意外と知られていないswitchの本当の能力

とび助
とび助
でもどうして、breakをつけ忘れると他のcaseも実行されてしまうんですか?
トビタカ
トビタカ
それはswitchの本当の能力が発動したからです。

 

意外と知られていないのですが、switch文の能力は『条件に当てはまるcaseの処理を実行する』というものではありません。

switch文の本当の能力は『当てはまったcase以降のすべての処理を実行する』というものなんです!

 

先程のプログラムの動作を思い出してください。

『1』を入力したときはcase1の条件に当てはまるので、『One』が表示されたと思います。

ここに『break;』があればswitch文は正常終了するのですが、書き忘れるとswitch文の本当の能力が発動してしまうんです。

つまり、case2の処理も実行されて『Two』も表示されてしまいます。

トビタカ
トビタカ
case2には『break;』をきちんと書いていたので、defalutはスキップされます!
とび助
とび助
なるほど!

 

このようにswitch文の本当の能力は『当てはまったcase以降のすべての処理を実行する』というものになります。

しかし、このままだと使いづらいので、『break』を書いてelse ifのような条件分岐として使っていたということなんですね。

breakを忘れると余計な処理まで実行してしまうので、switch文を使うときはbreakを忘れないように気を付けましょう!

フォールスルーが許される唯一の方法

とび助
とび助
フォールスルーは禁止ということで理解しました!
トビタカ
トビタカ
基本的には禁止なんですが、実は許されている使い方が1つだけあります!

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を連続して書いてしまいます。

そうすることで処理の内容が同じ条件をひとまとめにすることができるんです。

とび助
とび助
でもこれじゃあ、case1とcase3に当てはまらないと奇数とは表示されないんじゃないですか…?
トビタカ
トビタカ
先程のswitch文の本当の能力を思い出してください。

 

結論から言ってしまうと、先程のプログラムの場合はnumが1でも3でも『奇数』と表示されます。

というのも、switch文は条件に当てはまったcase以降のすべての処理を実行するからです。

そのため、case1に該当したらcase3に当てはまるかどうかは関係ありませんし。

case1に該当しなくても、case3に当てはまれば『奇数』と表示する処理が実行されます。

そして、きちんと処理の部分にbreakを書いておけば、問題なくswitch文を終了させることができるんです。

とび助
とび助
同じ処理があるときにはcaseをフォールスルーすればいいんですね!
トビタカ
トビタカ
その認識でOKですよ!

まとめ

以上がswitch文の動作異常を引き起こすフォールスルーとswitch文の本当の能力になります。

想定外の動作を引き起こすフォールスルーはかなり危険なので、breakのつけ忘れに注意しましょう。

フォールスルーのサマリ
トビタカ
トビタカ
caseをまとめるとき以外にフォールスルーをするとコンパイルエラーになるプログラム言語もありますよ。
とび助
とび助
それは安心ですね!

COMMENT

メールアドレスが公開されることはありません。 が付いている欄は必須項目です

CAPTCHA