switch文 - 整数の高速な条件分岐
switch文を使うと、整数の高速な条件分岐を行うことができます。
switch (値) {
case ケース1の値:
// 処理1
break;
case ケース2の値:
// 処理2
break;
case ケース3の値:
// 処理3
break;
default:
// 上記以外のケースの場合の処理
}
break文は必須ではありませんが、breakがない場合は、switch文の外には移動せずに、下の文が実行されます。
switch (値) {
case ケース1の値:
case ケース2の値:
// ケース1あるいはケース2の場合の処理
break;
case ケース3の値:
// 処理3
break;
default:
// 上記以外のケースの場合の処理
}
break文の記述のし忘れは、経験的に語ると、頻繁に発生します。「あれ、おかしいな、プログラムの動きが謎過ぎる」と思ったらbreak文書き忘れてたみたいな。
switch文のそれぞれの場合の処理では、変数宣言を行いたい場合も多いので、変数宣言を行いたい場合は、以下のようにスコープを作っておくとよいでしょう。
switch (値) {
case ケース1の値: {
// 処理1
break;
}
case ケース2の値: {
// 処理2
break;
}
case ケース3の値: {
// 処理3
break;
}
default: {
// 上記以外のケースの場合の処理
}
}
switch文を使ったサンプルです。列挙型と組み合わせて使っています。
#include <stdint.h>
#include <stdio.h>
enum {
SPVM_OP_C_ID_IF,
SPVM_OP_C_ID_UNLESS,
SPVM_OP_C_ID_ELSIF,
SPVM_OP_C_ID_ELSE,
SPVM_OP_C_ID_FOR,
};
int main(void) {
int32_t id = SPVM_OP_C_ID_UNLESS;
switch (id) {
case SPVM_OP_C_ID_IF: {
printf("IF\n");
break;
}
case SPVM_OP_C_ID_UNLESS: {
printf("UNLESS\n");
break;
}
case SPVM_OP_C_ID_ELSIF: {
printf("ELSIF\n");
break;
}
case SPVM_OP_C_ID_ELSE: {
printf("ELSE\n");
break;
}
case SPVM_OP_C_ID_FOR: {
printf("FOR\n");
break;
}
default: {
printf("No Match\n");
}
}
}
switch文の内部実装はどうなっていますか?
整数のパターンによって、二種類のジャンプテーブルが選択的に使われていると想像します。
整数の範囲が小さい場合
ジャンプ先のアドレスは、連続した整数位置に並べられ、計算量O(1)でジャンプできます。
5 0x1235 6 0x4568 7 NULL 8 NULL 9 0x3289
整数の範囲が大きい場合
ジャンプ先のアドレスは、二分探索が可能なように小さい順に並べられ、計算量O(log n)でジャンプできます。
5 0x1237 6 0x4563 7000 0x8768 10000 0x3284
if文とswitch文はどのように使い分けますか?
if文とswitch文はどのように使い分けるでしょうか?
switch文は、整数にマッチする場合にだけ使います。switch文は、列挙型との相性が非常によいです。
また、マッチさせる数が多い場合は、if文よりも速いです。たとえば、255個のIDで分岐したい場合は、switch文は高速で適しているといえます。
C言語ゼミ


