switch 文
条件式の値に応じて、いくつかの文のひとつに制御を転送します。
構文
attr(オプション) switch ( condition ) statement
|
(C++17未満) | ||||||||
attr(オプション) switch ( init-statement(オプション) condition ) statement
|
(C++17以上) | ||||||||
| attr(C++11) | - | 任意の個数の属性。 |
| condition | - | 整数型または列挙型または整数型か列挙型に文脈的に暗黙に変換可能なクラス型の任意の式、または波括弧または等号の初期化子付きのそのような型の単一の非配列変数の宣言。 |
| init-statement(C++17) | - | 以下のいずれか。
|
| statement | - | 任意の文 (一般的には複文)。 statement 内に case: および default: ラベルを置くことができ、 break; 文は特別な意味を持ちます。
|
attr(オプション) case constant_expression : statement
|
(1) | ||||||||
attr(オプション) default : statement
|
(2) | ||||||||
| constant_expression | - | 変換および整数昇格後の condition の型と同じ型の定数式。 |
説明
switch 文の本体は、すべての constant_expression の (変換/昇格後の) 値が一意である限り、任意の個数の case: ラベルを持つことができます。 また、多くとも1個の default: ラベルを持つことができます (ネストした switch 文はそれ自身の default: ラベルを持つことができ、外側の switch で使用されているものと同一の定数の case: ラベルを持つことができます)。
condition がいずれかの constant_expression の値と等しい値に評価された場合は、その constant_expression のラベルが付けられた文に制御が転送されます。
condition がいずれの case: ラベルにも一致しない値に評価され、 default: ラベルが存在する場合は、その default: ラベルが付けられた文に制御が転送されます。
statement 内で遭遇したとき、 break 文は switch 文を終了します。
switch(1) {
case 1 : cout << '1'; // 「1」表示し、
case 2 : cout << '2'; // その後「2」を表示します。
}
switch(1) {
case 1 : cout << '1'; // 「1」表示し、
break; // その後 switch を終了します。
case 2 : cout << '2';
break;
}
|
コンパイラは、フォールスルー (break なしで次の case ラベルに到達すること) に対して警告を発行するかもしれません。 ただし、そのフォールスルーが意図的であることを表すために case ラベルの直前に属性 init-statement が使用された場合、その switch 文は以下と同等です。
ただし、 init-statement によって宣言された名前 (init-statement が宣言の場合) および condition によって宣言された名前 (condition が宣言の場合) は同じスコープであり、それは statement のスコープでもあります。 |
(C++17以上) | |||||||||||||||||||||||
制御の転送は変数のスコープに入ることは許されていないため、 statement の内部に宣言文がある場合は、それ自身の複文内にスコープ化される必要があります。
switch(1) {
case 1: int x = 0; // 初期化
std::cout << x << '\n';
break;
default: // コンパイルエラー、 default: へのジャンプは
// 'x' を初期化せずにそのスコープに入ります。
std::cout << "default\n";
break;
}
switch(1) {
case 1: { int x = 0;
std::cout << x << '\n';
break;
} // 'x' のスコープはここで終わります。
default: // OK
std::cout << "default\n";
break;
}
キーワード
例
以下のコードは switch 文のいくつかの使い方の例を示します。
#include <iostream>
int main()
{
int i = 2;
switch (i) {
case 1: std::cout << "1";
case 2: std::cout << "2"; // 実行はこの case ラベルから始まります。
case 3: std::cout << "3";
case 4:
case 5: std::cout << "45";
break; // 後続の文の実行は終了します。
case 6: std::cout << "6";
}
std::cout << '\n';
switch (i) {
case 4: std::cout << "a";
default: std::cout << "d"; // 適用可能な constant_expression は存在せず、
// そのため default が実行されます。
}
std::cout << '\n';
switch (i) {
case 4: std::cout << "a"; // 何も実行されません。
}
// switch 文で列挙が使用された場合、多くのコンパイラは
// 列挙のいずれかが処理されていなければ警告を発行します。
enum color {RED, GREEN, BLUE};
switch(RED) {
case RED: std::cout << "red\n"; break;
case GREEN: std::cout << "green\n"; break;
case BLUE: std::cout << "blue\n"; break;
}
// 整数または列挙型への暗黙の変換がないとき、
// C++17 の init-statement 構文が役に立ちます。
switch (Device dev = get_device(); dev.state())
{
case SLEEP: /*...*/ break;
case READY: /*...*/ break;
case BAD: /*...*/ break;
}
// 病的な例
// statement が複文である必要はありません。
switch(0)
std::cout << "this does nothing\n";
// ラベルも複文を要求しません。
switch(int n = 1)
case 0:
case 1: std::cout << n << '\n';
// Duff's Device: https://ja.wikipedia.org/wiki/Duff's_device
}
出力:
2345
d
red
1
関連項目
switch の C言語リファレンス
|