名前空間
変種
操作

switch 文

提供: cppreference.com
< cpp‎ | language
 
 
C++言語
一般的なトピック
フロー制御
条件付き実行文
switch
繰り返し文 (ループ)
ジャンプ文
関数
関数宣言
ラムダ関数宣言
inline 指定子
例外指定 (C++20未満)
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";   // 実行はこの 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

[編集] 関連項目