こんにちは!フリーランスの長野です。
switch-case文って使ってますか?switch-case文は条件によって処理を分ける数が複数で多い場合に使われます。
例えばサイコロの目は1から6までありますが、1から6までの出た目でそれぞれ処理が違う場合などです。
また、C言語ではenumで定数を定義し、その定数名つまり文字列を使って条件分岐を記述することができます。
この記事では、switch-case文について
- switch-case文とは
- switch-case文、default句の使い方
という基本的な内容から、
- enumを使って文字列で複数条件分岐
- [補足]ループ文の中での挙動について
など応用的な使い方の内容についても解説していきます。
今回はswitch-case文について、使い方をわかりやすく解説します!
switch-case文とは
swtich-case文は条件によって処理を変える場合に使われます。条件によって処理を変える構文としてif文もあります。
if文は条件によって処理を分ける数が少ないのに対して、switch文は条件によって分ける処理が多い場合に使われます。
switch-case文、default句の使い方
swtich-case文は次のように記述します。
switch(式) { case 値1: 式の結果と値1が一致したときの処理 break; case 値2: 式の結果と値2が一致したときの処理 break; default: 式の結果がどの値とも一致しなかったときの処理 }
swtich-case文では値が一致して処理を行ったあとに「break」句を使って処理を抜けなければ、後の処理が続けて実行されてしまいますので注意してください。
値が一致しなかった場合の処理は「default:」句のあとに記述します。
基本的な使い方
簡単な使い方についてサンプルコードでみていきましょう。
#include <stdio.h> int main(void) { // サイコロの出目 int num = 3; switch(num) { case 1: printf("一の目が出ました\n"); break; case 2: printf("二の目が出ました\n"); break; case 3: printf("三の目が出ました\n"); break; case 4: printf("四の目が出ました\n"); break; case 5: printf("五の目が出ました\n"); break; case 6: printf("六の目が出ました\n"); break; default: printf("numの値が不正です\n"); } return 0; }
実行結果:
三の目が出ました
このサンプルコードでは、int型の変数「num」が1から6のいずれかの値と一致した場合に、それぞれの処理が行われます。
defaultの使い方
defaultでは値が一致しなかった場合の処理を記述します。
簡単な使い方についてサンプルコードでみていきましょう。
#include <stdio.h> int main(void) { // サイコロの出目 int num = 0; switch(num) { case 1: printf("一の目が出ました\n"); break; case 2: printf("二の目が出ました\n"); break; case 3: printf("三の目が出ました\n"); break; case 4: printf("四の目が出ました\n"); break; case 5: printf("五の目が出ました\n"); break; case 6: printf("六の目が出ました\n"); break; default: printf("numの値が不正です\n"); } return 0; }
実行結果:
numの値が不正です
このサンプルコードでは、int型の変数「num」が1から6のいずれかの値と一致した場合に、それぞれの処理が行われますが、変数「num」に代入された値は0(ゼロ)です。
1から6の値のいずれとも一致しませんので、defaultで定義した処理が実行されています。
enumを使って文字列で複数条件分岐
enumで宣言した文字列名を使ってswitch-case文を記述することができます。enumの定数は0(ゼロ)から順に整数が割り当てられるからです。enumはオブジェクトを定義し、そのオブジェクトにenumの定数を代入して使用します。
switch文の式にはenumのオブジェクトを記述し、caseの値にはenumの定数名つまり文字列名を記述することができます。
サンプルコードで確認していきましょう。
#include <stdio.h> enum week { Mon, Tue, Wed, Thu, Fri, Sat, Sun }; int main(void) { enum week wk; // enum型のオブジェクトを定義 wk = Wed; // enum型の定数を代入 switch(wk) { case Mon: case Tue: case Wed: case Thu: case Fri: printf("平日です\n"); break; case Sat: case Sun: printf("休日です\n"); break; default: printf("不正です\n"); } return 0; }
実行結果:
平日です
このサンプルコードではenum型のオブジェクト「wk」を定義しています。オブジェクト「wk」にenum型「week」の定数「Wed」を代入しています。
switch文の式にはwkを記述し、caseの値にはenum型「week」の定数を指定しています。caseの値にはenum型「week」の定数つまり文字列名を記述しているので、場合分けの条件が読みやすくなるメリットがあります。
なお、このswitch-case文ではいくつかのcaseで「break」句を記述していません。
いくつかのcaseで同じ処理を行いたい場合は、そのcaseで「break」句を記述しなければ、次に記述された「break」句に到達するまで処理が続きます。
そうすることで同じ処理でまとめることができます。
[補足]ループ文の中での挙動について
今回switch文で使用した「break」句。プログラムに詳しい人なら、ループを抜けるために使ったりすることもご存知でしょう。
ではループ文の内部に、switch文を書いている場合に使用した「break」句はどんな挙動をするのでしょう?
for([条件]) { switch(1) { case 1: break; // このbreak句 } }
例えばこんな状況下でのbreak句です。これはループ処理に反映されるのか?switch文に反映してくれるのか?
最後にそれを知っておきましょう!
またループ文の時に「break」句と合わせてよく使われる「continue」句での挙動も合わせてみておきましょうか。
break句はどこに反映されるの?
以下はfor文の中のswitch文を使っているサンプルコードです。
#include <stdio.h> int main(void) { // ループ回数のカウント変数 int loop_num; printf("ループを開始します\n"); for(loop_num = 1; loop_num <= 3; loop_num++) { // 「case 1」へ行くだけの switch文 printf("%d回目のループで、switch文開始\n", loop_num); switch(1) { case 1: printf("%d回目のループで、1に来ました\n", loop_num); break; case 2: printf("%d回目のループで、2に来ました\n", loop_num); break; } printf("%d回目のループで、switch文終了\n", loop_num); } printf("ループを終了しました\n"); return 0; }
実行結果:
ループを開始します 1回目のループで、switch文開始 1回目のループで、1に来ました 1回目のループで、switch文終了 2回目のループで、switch文開始 2回目のループで、1に来ました 2回目のループで、switch文終了 3回目のループで、switch文開始 3回目のループで、1に来ました 3回目のループで、switch文終了 ループを終了しました
for文の内部で、break句を使用すると、forを抜けるはずですが…
ループは終了されていません。switch文の中で使用する場合は、switch文へ反映されて、ループ文へは影響していないことがわかると思います。
実戦ではよくある組み合わせなので、初心者の方はこのことはよく覚えておきましょう。
ではcontinue句は?
では同じ状況でcontinue句を使ったらどうなるのか?実際使うかどうかは置いておいて、ちょっと気になってしまうところですね!
早速みてみましょう。
#include <stdio.h> int main(void) { // ループ回数のカウント変数 int loop_num; printf("ループを開始します\n"); for(loop_num = 1; loop_num <= 3; loop_num++) { // 「case 1」へ行くだけの switch文 printf("%d回目のループで、switch文開始\n", loop_num); switch(1) { case 1: printf("%d回目のループで、1に来ました(continue前)\n", loop_num); continue; printf("%d回目のループで、1に来ました(continue後)\n", loop_num); break; case 2: printf("%d回目のループで、2に来ました\n", loop_num); break; } printf("%d回目のループで、switch文終了\n", loop_num); } printf("ループを終了しました\n"); return 0; }
実行結果:
ループを開始します 1回目のループで、switch文開始 1回目のループで、1に来ました(continue前) 2回目のループで、switch文開始 2回目のループで、1に来ました(continue前) 3回目のループで、switch文開始 3回目のループで、1に来ました(continue前) ループを終了しました
ちょっと表示が多くややこしく感じるかもしれませんが…
中でも重要な箇所は結果の以下の部分です。
1回目のループで、1に来ました(continue前) 2回目のループで、switch文開始
continueへ来た時に「continue後」や「switch文終了」の表示が行われずに、2回目のループが開始されています。
「次のループが始まった」つまり、ループ文へ影響したということです。
- switch文内部のbreak句は、外のループ文へ影響しない
- switch文内部のcontinue句は、外のループ文へ影響する
地味に混乱を招く場所なので、このことは覚えておきましょう。
※実際phpでは、switch文内の、continu句はbreak句として扱われたりします。複数言語を扱う人ほど混乱する場所です。覚えておきましょう。
まとめ
ここでは、switch-case文について説明しました。switch-case文は条件によって処理を分ける数が多い場合に使うと便利です。
またenumの定数を使って記述すると文字列名で場合分けを記述できるので読みやすくなります。
使いこなすことができるように、この記事を何度も参考にして下さいね!