名前空間
変種
操作

switch 文

提供: cppreference.com
< cpp‎ | language
 
 
C++言語
一般的なトピック
フロー制御
条件付き実行文
switch
繰り返し文 (ループ)
ジャンプ文
関数
関数宣言
ラムダ関数宣言
inline 指定子
例外指定 (非推奨)
noexcept 指定子 (C++11)
例外
名前空間
指定子
decltype (C++11)
auto (C++11)
alignas (C++11)
記憶域期間指定子
初期化
代替表現
リテラル
ブーリアン - 整数 - 浮動小数点
文字 - 文字列 - nullptr (C++11)
ユーザ定義 (C++11)
ユーティリティ
属性 (C++11)
typedef 宣言
型エイリアス宣言 (C++11)
キャスト
暗黙の変換 - 明示的な変換
static_cast - dynamic_cast
const_cast - reinterpret_cast
メモリ確保
クラス
クラス固有の関数特性
特別なメンバ関数
テンプレート
その他
 
ラベル
label : statement
式文
expression ;
複合文
{ statement... }
選択文
if
switch
繰り返し文
while
do-while
for
範囲 for(C++11)
ジャンプ文
break
continue
return
goto
宣言文
declaration ;
try ブロック
try compound-statement handler-sequence
トランザクショナルメモリ
synchronized, atomic_commit など(TM TS)
 

条件式の値に応じて、いくつかの文のひとつに制御を転送します。

目次

[編集] 構文

attr(オプション) switch ( condition ) statement (C++17以前)
attr(オプション) switch ( init-statement(オプション) condition ) statement (C++17およびそれ以降)
attr(C++11) - 任意の個数の属性
condition - 整数型または列挙型または整数型か列挙型に文脈的に暗黙に変換可能なクラス型の任意の、または波括弧または等号の初期化子付きのそのような型の単一の非配列変数の宣言
init-statement(C++17) - 以下のいずれか。
  • 式文 (空文;」でも構いません)。
  • 単純宣言。 一般的には初期化子付きの1個の変数の宣言ですが、好きなだけ多くの変数や構造化束縛を宣言しても構いません。
あらゆる init-statement はセミコロン ; で終わらなければならないことに注意してください。 これが式または宣言にセミコロンが続いたものとしてしばしば非形式的に説明される理由です。
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 ラベルの直前に属性 [[fallthrough]] がある場合は除きます。

init-statement が使用された場合、その switch 文は以下と同等です。

{
init-statement
switch ( condition ) statement

}

ただし、 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, case, default

[編集]

以下のコードは switch 文のいくつかの使い方の例を示します。

#include <iostream>
 
int main()
{
    int i = 2;
    switch (i) {
        case 1: std::cout << "1";
        case 2: std::cout << "2";   //execution starts at this case label
        case 3: std::cout << "3";
        case 4:
        case 5: std::cout << "45";
                break;              //execution of subsequent statements is terminated
        case 6: std::cout << "6";
    }
 
    std::cout << '\n';
 
    switch (i) {
        case 4: std::cout << "a";
        default: std::cout << "d"; //there are no applicable constant_expressions 
                                   //therefore default is executed
    }
 
    std::cout << '\n';
 
    switch (i) {
        case 4: std::cout << "a";  //nothing is executed
    }
 
    // when enumerations are used in a switch statement, many compilers
    // issue warnings if one of the enumerators is not handled
    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;
    }
 
    // the C++17 init-statement syntax can be helpful when there is
    // no implicit conversion to integral or enumeration type
    switch (Device dev = get_device(); dev.state())
    {
       case SLEEP: /*...*/ break;
       case READY: /*...*/ break;
       case BAD: /*...*/ break;
    }
 
    // pathological examples
 
    // the statement doesn't have to be a compound statement
    switch(0)
        std::cout << "this does nothing\n";
 
    // labels don't require a compound statement either
    switch(int n = 1)
        case 0:
        case 1: std::cout << n << '\n';
 
    // Duff's Device: http://en.wikipedia.org/wiki/Duff's_device
}

出力:

2345
d
red
1

[編集] 関連項目