https://youtu.be/9brC1Cg_sMc
\textcolor{pink}{四国めたん: } 教師役ですわ
\textcolor{lime}{ずんだもん: } 生徒役なのだ
\footnotesize \textcolor{pink}{四国めたん:} 皆さん、こんにちは。四国めたんです
\footnotesize \textcolor{lime}{ずんだもん:} ずんだもんなのだ。こんにちはなのだ
\footnotesize \textcolor{pink}{四国めたん:} 今回もC言語のお勉強をしていきましょう
\footnotesize \textcolor{lime}{ずんだもん:} レッツゴーなのだ
\footnotesize \textcolor{pink}{四国めたん:} 前回は、 無条件ジャンプ についてお話ししましたわ
\footnotesize \textcolor{lime}{ずんだもん:} そうだったのだ
\footnotesize \textcolor{pink}{四国めたん:} 今回はswitch
~case
文についてお話ししますわ
\footnotesize \textcolor{lime}{ずんだもん:} switch
~case
文?
\footnotesize \textcolor{pink}{四国めたん:} はい、指定した「式」の結果に応じて、予め決めた場所にジャンプするための構文ですわ
\footnotesize \textcolor{lime}{ずんだもん:} 「式」に応じてと云うことは、if
文と同じような感じか?
\footnotesize \textcolor{pink}{四国めたん:} 同じようなことは可能ですが、基本的な動作は全く異なりますわね
\footnotesize \textcolor{lime}{ずんだもん:} そうなのか?
\footnotesize \textcolor{pink}{四国めたん:} 同一に扱うプログラマーもいらっしゃいますが、しっかりと区別した方がいいですわね
\footnotesize \textcolor{lime}{ずんだもん:} りょうかいなのだ
\footnotesize \textcolor{lime}{ずんだもん:} ところで、今回も おまけ なのか?
\footnotesize \textcolor{pink}{四国めたん:} はい、基本的にswitch
~case
文も、できれば使ってほしくありませんわ
\footnotesize \textcolor{lime}{ずんだもん:} 使ってほしくないのに解説するのか?
\footnotesize \textcolor{pink}{四国めたん:} はい、文法として決められている以上、switch
~case
文が使われているプログラムも多く存在しますわ
\footnotesize \textcolor{lime}{ずんだもん:} そうなのか?
\footnotesize \textcolor{pink}{四国めたん:} そのようなプログラムを読んだ時に、意味が解らないのでは困ることになりますわ
\footnotesize \textcolor{lime}{ずんだもん:} たしかにその通りなのだ
\footnotesize \textcolor{pink}{四国めたん:} とくにswitch
~case
文は、どのように動作するかをしっかりと把握していないと、間違ってしまうもとになりますわ
\footnotesize \textcolor{lime}{ずんだもん:} 気をつけるのだ
switch ~ case
\footnotesize \textcolor{pink}{四国めたん:} まず、switch
~case
文は、指定した「式」の戻り値に合ったラベルにジャンプする構文ですわ
\footnotesize \textcolor{lime}{ずんだもん:} うん?条件に応じて分岐するのではないのか?
\footnotesize \textcolor{pink}{四国めたん:} 基本的にはgoto
ジャンプに近いと思いますわ
\footnotesize \textcolor{lime}{ずんだもん:} そうなのか?
\footnotesize \textcolor{pink}{四国めたん:} とりあえず具体的な形式を見てみましょう
switch (式) {
case 値0:
処理0
case 値1:
処理1
case 値2:
処理2
:
:
default:
処理
}
\footnotesize \textcolor{pink}{四国めたん:} まず、switch
の後に「式」を括弧"()"で括って記述しますわ
\footnotesize \textcolor{lime}{ずんだもん:} ふむ
\footnotesize \textcolor{pink}{四国めたん:} この「式」の戻り値がジャンプ先のラベルとなりますわ
\footnotesize \textcolor{lime}{ずんだもん:} ラベルと云うと、本当にgoto
のような感じなのだな
\footnotesize \textcolor{pink}{四国めたん:} 波括弧"{}"内では、case
に続けてラベルの代わりとなる値とコロン":"を記述しますわ
\footnotesize \textcolor{lime}{ずんだもん:} 値と云うと、数値をラベルとして使うのか?
\footnotesize \textcolor{pink}{四国めたん:} はい、ジャンプ先のラベルとしての値は、整数値かそれに準ずる、たとえば列挙子などを用いますわ
\footnotesize \textcolor{lime}{ずんだもん:} 列挙子も使えるのか...
\footnotesize \textcolor{pink}{四国めたん:} 当然、「式」の戻り値も整数値か列挙子などである必要がありますわね
\footnotesize \textcolor{lime}{ずんだもん:} りょうかいなのだ
\footnotesize \textcolor{pink}{四国めたん:} ちなみに「ラベルへのジャンプ」なので、たとえばcase 値0:
にジャンプ後は、処理0、処理1、処理2...と、全ての処理が実行されますわ
\footnotesize \textcolor{lime}{ずんだもん:} えぇっ、case
と次のcase
に挟まれた部分の処理のみが実行されるのではないのか!?
\footnotesize \textcolor{pink}{四国めたん:} ちがいますわね
\footnotesize \textcolor{pink}{四国めたん:} その辺りが 条件分岐 ではなく、ラベルへのジャンプとした理由ですわ
\footnotesize \textcolor{lime}{ずんだもん:} りょうかいなのだ
\footnotesize \textcolor{pink}{四国めたん:} なお、case
で指定された値以外が「式」の戻り値になった場合には、default:
にジャンプしますわ
\footnotesize \textcolor{lime}{ずんだもん:} default:
がない場合はどうなるのだ?
\footnotesize \textcolor{pink}{四国めたん:} もし、default:
もない場合には、switch
文をスキップして、次の処理に移りますわ
\footnotesize \textcolor{lime}{ずんだもん:} なるほどなのだ
\footnotesize \textcolor{pink}{四国めたん:} とりあえず実例を見てみましょう
#include <stdio.h>
#include <conio.h>
void main() {
int c = 0;
do {
printf("キーボードから文字を入力して下さい\n");
c = _getch();
switch (c) {
case 'a':
printf("aが入力されました\n");
case 'b':
printf("bが入力されました\n");
case 'c':
printf("cが入力されました\n");
default:
printf("abc以外が入力されました\n");
}
} while (c != 'z');
printf("プログラムを終了します\n");
}
\footnotesize \textcolor{pink}{四国めたん:} キーボードから1文字ずつ入力して、\fcolorbox{blue}{lightgray}{a} , \fcolorbox{blue}{lightgray}{b} , \fcolorbox{blue}{lightgray}{c} の場合には出力され、それ以外は「abc以外が入力されました」と出力されますわ
\footnotesize \textcolor{lime}{ずんだもん:} ラベルには'a', 'b', 'c'のように文字を指定しているのだ
\footnotesize \textcolor{pink}{四国めたん:} はい、以前にもお話ししましたが、char
型の文字は整数と同じですから...
\footnotesize \textcolor{lime}{ずんだもん:} 覚えているのだ
\footnotesize \textcolor{pink}{四国めたん:} そして、\fcolorbox{blue}{lightgray}{z} を入力するとプログラムを終了しますわ
\footnotesize \textcolor{lime}{ずんだもん:} うむ
\footnotesize \textcolor{pink}{四国めたん:} それでは実行して、キーボードから\fcolorbox{blue}{lightgray}{b} を入力してみましょう
\footnotesize \textcolor{lime}{ずんだもん:} 「bが入力されました」、「cが入力されました」、「abc以外が入力されました」と表示されたのだ
\footnotesize \textcolor{pink}{四国めたん:} なお「式」の部分を少し変更して、ラベルに整数を使うことも可能ですわ
#include <stdio.h>
#include <conio.h>
void main() {
int c = 0;
do {
printf("キーボードから文字を入力して下さい\n");
c = _getch();
switch (c - 'a') {
case 0:
printf("aが入力されました\n");
case 1:
printf("bが入力されました\n");
case 2:
printf("cが入力されました\n");
default:
printf("abc以外が入力されました\n");
}
} while (c != 'z');
printf("プログラムを終了します\n");
}
\footnotesize \textcolor{pink}{四国めたん:} ちなみに、ずんだもんさんは「bが入力されました」とだけ表示されると期待しましたか?
\footnotesize \textcolor{lime}{ずんだもん:} たしかにその通りなのだ
\footnotesize \textcolor{pink}{四国めたん:} ですが、switch
文は「式」の戻り値をラベルとしてジャンプするだけなので、ジャンプ先以降の処理は全て実行されるのですわ
\footnotesize \textcolor{lime}{ずんだもん:} そうだったのだ
\footnotesize \textcolor{pink}{四国めたん:} この点は非常に重要で、忘れがちな点でもありますわ
\footnotesize \textcolor{lime}{ずんだもん:} じゅうぶん、注意するのだ
\footnotesize \textcolor{pink}{四国めたん:} この性質を利用して、「式」の異なる戻り値に対して、同じ位置にジャンプさせることもできますわ
\footnotesize \textcolor{lime}{ずんだもん:} そうなのか?
\footnotesize \textcolor{pink}{四国めたん:} とりあえず実例を見てみましょう
#include <stdio.h>
#include <conio.h>
void main() {
int c = 0;
do {
printf("キーボードから文字を入力して下さい\n");
c = _getch();
switch (c) {
case 'a':
case 'b':
case 'c':
printf("abcが入力されました\n");
default:
printf("abc以外が入力されました\n");
}
} while (c != 'z');
printf("プログラムを終了します\n");
}
\footnotesize \textcolor{pink}{四国めたん:} この場合、キーボードの入力\fcolorbox{blue}{lightgray}{a} , \fcolorbox{blue}{lightgray}{b} , \fcolorbox{blue}{lightgray}{c} に対して、同じprintf("abcが入力されました\n");
の部分に処理が移りますわ
\footnotesize \textcolor{lime}{ずんだもん:} なるほどなのだ
breakを使ったswitch
\footnotesize \textcolor{pink}{四国めたん:} はい、ここまでがswitch
文の基本的な動作のお話しですわ
\footnotesize \textcolor{lime}{ずんだもん:} うむ
\footnotesize \textcolor{pink}{四国めたん:} ところで、ずんだもんさんは、「式」の戻り値に対してcase
のラベル毎に異なる処理がおこなわれることを期待していましたわね
\footnotesize \textcolor{lime}{ずんだもん:} その通りなのだ
\footnotesize \textcolor{pink}{四国めたん:} 実は、ジャンプして、それ以降の処理を全て実行するような使い方は、一般的ではありませんわ
\footnotesize \textcolor{lime}{ずんだもん:} そうなのか?
\footnotesize \textcolor{pink}{四国めたん:} むしろ、期待した通り、if
文のような 条件分岐 的な使い方のほうが一般的ですわ
\footnotesize \textcolor{lime}{ずんだもん:} ふむふむ
\footnotesize \textcolor{pink}{四国めたん:} その場合、break
を併用して、このような形式になりますわ
switch (式) {
case 値0:
処理0
break;
case 値1:
処理1
break;
case 値2:
処理2
break;
:
:
default:
処理
break;
}
\footnotesize \textcolor{lime}{ずんだもん:} 詳しく教えて欲しいのだ
\footnotesize \textcolor{pink}{四国めたん:} はい、各処理の最後、次のcase
の直前にbreak
を置くことで、各case
後の処理が終わったら、強制的にswitch
文の外にジャンプしますわ
\footnotesize \textcolor{lime}{ずんだもん:} なるほどなのだ
\footnotesize \textcolor{pink}{四国めたん:} なお、default
後の処理の後のbreak
は、本来、必要ないのですが、様式美と云うことで入れていますわ
\footnotesize \textcolor{lime}{ずんだもん:} まぁ、全てにbreak
を入れるようにしておけば、忘れる可能性が減るのだ
\footnotesize \textcolor{pink}{四国めたん:} ちなみに、このような使い方は、break
の、唯一、推奨される使い方ですわ
\footnotesize \textcolor{lime}{ずんだもん:} そうなのか?
\footnotesize \textcolor{pink}{四国めたん:} とりあえずサンプルプログラムを見てみましょう
#include <stdio.h>
#include <conio.h>
void main() {
int c = 0;
do {
printf("キーボードから文字を入力して下さい\n");
c = _getch();
switch (c) {
case 'a':
printf("aが入力されました\n");
break;
case 'b':
printf("bが入力されました\n");
break;
case 'c':
printf("cが入力されました\n");
break;
default:
printf("abc以外が入力されました\n");
break;
}
} while (c != 'z');
printf("プログラムを終了します\n");
}
\footnotesize \textcolor{pink}{四国めたん:} 実行してキーボードから\fcolorbox{blue}{lightgray}{b} を入力してみますわ
\footnotesize \textcolor{pink}{四国めたん:} 今回は「bが入力されました」とだけ表示されて、「cが入力されました」などの余計な表示はされていませんわ
\footnotesize \textcolor{lime}{ずんだもん:} break
を使わなかった時とは全然違うのだ
\footnotesize \textcolor{pink}{四国めたん:} なお、break
を伴ったswitch
文は、概ねif
文の 条件分岐 と同じですわ
\footnotesize \textcolor{lime}{ずんだもん:} 期待した使い方なのだ
#include <conio.h>
#include <stdio.h>
void main() {
int c = 0;
do {
printf("キーボードから文字を入力して下さい\n");
c = _getch();
if (c == 'a') {
printf("aが入力されました\n");
} else if (c == 'b') {
printf("bが入力されました\n");
} else if (c == 'c') {
printf("cが入力されました\n");
} else {
printf("abc以外が入力されました\n");
}
} while (c != 'z');
printf("プログラムを終了します\n");
}
\footnotesize \textcolor{lime}{ずんだもん:} お~、if
文を使って同じことが可能なのだ
\footnotesize \textcolor{pink}{四国めたん:} なお、このような 条件分岐 的な使い方の場合、if
文よりもswitch
文を好むプログラマーもいらっしゃいますわ
\footnotesize \textcolor{lime}{ずんだもん:} どうしてなのだ?
\footnotesize \textcolor{pink}{四国めたん:} 理由としては、「if
文よりもswitch
文の方が速い」とか「見た目にきれい」だとかが上げられますわ
\footnotesize \textcolor{lime}{ずんだもん:} そうなのか?
\footnotesize \textcolor{pink}{四国めたん:} まぁ、たしかにif
文よりもswitch
文の方が速くなる場合があるのも事実ですわ
\footnotesize \textcolor{pink}{四国めたん:} でも、昔ならいざ知らず、現在のコンパイラやCPUでは、気にする程の差異はないと思いますわ
\footnotesize \textcolor{lime}{ずんだもん:} なるほどなのだ
\footnotesize \textcolor{pink}{四国めたん:} また、switch
の方が「見た目がきれい」なのは理解はしますが、break
を忘れてバグに苦しんだりすることを考えると、あえてswitch
文を勧めたいとは思いませんわ
\footnotesize \textcolor{lime}{ずんだもん:} りょうかいなのだ
複数の条件に同じ処理を
\footnotesize \textcolor{pink}{四国めたん:} ちなみに、あえてbreak
を使わない部分を作って、複数の条件に同じ処理をさせることも可能ですわ
\footnotesize \textcolor{lime}{ずんだもん:} それは便利なのだ
\footnotesize \textcolor{pink}{四国めたん:} とりあえずサンプルを見てみましょう
#include <stdio.h>
#include <conio.h>
void main() {
int c = 0;
do {
printf("キーボードから文字を入力して下さい\n");
c = _getch();
switch (c) {
case 'a':
case 'b':
case 'c':
printf("abcが入力されました\n");
break;
default:
printf("abc以外が入力されました\n");
break;
}
} while (c != 'z');
printf("プログラムを終了します\n");
}
\footnotesize \textcolor{pink}{四国めたん:} 実行してキーボードから\fcolorbox{blue}{lightgray}{a} , \fcolorbox{blue}{lightgray}{b} , \fcolorbox{blue}{lightgray}{c} と入力してみますわ
\footnotesize \textcolor{lime}{ずんだもん:} 全てに対して「abcが入力されました」と表示されたのだ
\footnotesize \textcolor{pink}{四国めたん:} そしてbreak
があるため、以前のように「abc以外が入力されました」と云う表示はされませんわ
defaultは必須です
\footnotesize \textcolor{lime}{ずんだもん:} ところで、switch
文でdefault
は必須なのか?
\footnotesize \textcolor{pink}{四国めたん:} いいえ、default
がない場合、case
のラベルに「式」の戻り値に該当する値がなければ、そのままswitch
文を抜けるだけですわ
\footnotesize \textcolor{lime}{ずんだもん:} なるほどなのだ
\footnotesize \textcolor{pink}{四国めたん:} ただ、バグを減らすという観点から、default
は必ず記述することをお勧めしますわ
\footnotesize \textcolor{lime}{ずんだもん:} そうなのか?
\footnotesize \textcolor{pink}{四国めたん:} 処理が必要なければ、break
だけでもOKですわ
\footnotesize \textcolor{lime}{ずんだもん:} なるほどなのだ
\footnotesize \textcolor{pink}{四国めたん:} コメントで処理が必要ないことを明記すると、なお良いですわ
\footnotesize \textcolor{lime}{ずんだもん:} うむ
\footnotesize \textcolor{pink}{四国めたん:} これは、デフォルトの処理が必要なのに書き忘れてしまい、バグになってしまうケースが多いからですわ
\footnotesize \textcolor{lime}{ずんだもん:} そうなのか?
\footnotesize \textcolor{pink}{四国めたん:} また、case
部分で「式」の戻り値の全てを網羅したつもりが、網羅できていなかった場合にも有用ですわね
\footnotesize \textcolor{lime}{ずんだもん:} なるほど、default
にエラーメッセージを出力するようにしておけば、バグの発見に有効なのだ
\footnotesize \textcolor{pink}{四国めたん:} そうですわね
switchにcontinue
!
switch
文にbreak
を使えるなら、代わりにcontinue
も使えるのではないかと思いませんか?
使えません
全く意味が違ってきてしまいます
とりあえず、break
の1つをcontinue
に置き換えて、switch
文の後に文字列を出力してみます
#include <stdio.h>
#include <conio.h>
void main() {
int c = 0;
do {
printf("キーボードから文字を入力して下さい\n");
c = _getch();
switch (c) {
case 'a':
printf("aが入力されました\n");
break;
case 'b':
printf("bが入力されました\n");
continue;
case 'c':
printf("cが入力されました\n");
break;
default:
printf("abc以外が入力されました\n");
break;
}
printf("switchを抜けました\n");
} while (c != 'z');
printf("プログラムを終了します\n");
}
実行してキーボードから\fcolorbox{blue}{lightgray}{a} , \fcolorbox{blue}{lightgray}{b} , \fcolorbox{blue}{lightgray}{c} と入力してみます
break
をcontinue
に変えた、\fcolorbox{blue}{lightgray}{b} の場合のみ、seitch
文後の文字列出力「switchを抜けました」がありません
つまり、continue
はswitch
文に作用するのではなく、do
~while
ループに作用して、ループの最初にジャンプしているのです
まとめ
\footnotesize \textcolor{pink}{四国めたん:} お疲れさまでした
\footnotesize \textcolor{lime}{ずんだもん:} おつかれさまなのだ
\footnotesize \textcolor{pink}{四国めたん:} 以上で Switch についてのお話しを終わりますわ
\footnotesize \textcolor{pink}{四国めたん:} ところで、switch
~case
文はif
~else
文とは全く異なるものですわ
\footnotesize \textcolor{lime}{ずんだもん:} たしかにその通りなのだ
\footnotesize \textcolor{pink}{四国めたん:} if
~else
文は 条件分岐 ですが、switch
~case
文は 無条件ジャンプ に属するものと思った方がいいと思いますわ
\footnotesize \textcolor{lime}{ずんだもん:} うむ
Discussion