Namespaces
Variants

switch statement

From cppreference.net

整数引数の値に応じてコードを実行します。

多くのコード分岐のうち1つまたは複数を、整数値に基づいて実行する必要がある場合に使用されます。

目次

構文

attr-spec-seq (オプション) switch ( expression ) statement
attr-spec-seq - (C23) オプションの 属性 リスト、 switch 文に適用される
expression - 任意の 整数型 (char、符号付きまたは符号なし整数、または列挙型))
statement - 任意の (通常は複合文)。 case: および default: ラベルは statement 内で許可され、 break ; 文は特別な意味を持つ。
case 定数式 : (1) (C23まで)
属性指定子並び (オプション) case 定数式 : (オプション) (1) (C23以降)
default : (2) (C23まで)
属性指定子並び (オプション) default : (オプション) (2) (C23以降)
constant-expression - 任意の整数 constant expression
attr-spec-seq - (C23) オプションの attributes リスト、ラベルに適用される

説明

switch文の本体は任意の数の case: ラベルを持つことができますが、すべての constant-expressions の値が( conversion を経て promoted type に変換された後)一意である必要があります。最大で1つの default: ラベルが存在できます(ただし、入れ子になったswitch文は独自の default: ラベルを使用したり、外側のswitchで使用された定数と同一の定数を持つ case: ラベルを持つことができます)。

expression が、その型が expression の昇格型に変換された後の constant-expression の値のいずれかに等しい値に評価される場合、制御はその constant-expression でラベル付けされた文に移ります。

expression がどの case: ラベルにも一致しない値を評価し、かつ default: ラベルが存在する場合、制御は default: ラベルで指定された文に移ります。

expression がどの case: ラベルにも一致しない値を評価し、かつ default: ラベルが存在しない場合、switch文の本体は一切実行されません。

break 文は、 statement 内のどこで検出されても、switch文を終了します:

switch(1) {
    case 1 : puts("1"); // "1"を出力し、
    case 2 : puts("2"); // 続いて"2"を出力する(フォールスルー)
}
switch(1) {
    case 1 : puts("1"); // "1"を出力
             break;     // そしてswitch文を終了
    case 2 : puts("2");
             break;
}

他のすべての選択文および反復文と同様に、switch文は ブロックスコープ を確立します: expression 内で導入された識別子は statement の後にスコープから外れます。

可変長配列(VLA)または可変修飾型を持つ他の識別子が、そのスコープ内に case: または default: ラベルを持つ場合、switch文全体がそのスコープ内になければなりません(つまり、VLAはswitch文全体の前か、最後のラベルの後に宣言する必要があります):

switch (expr)
{
        int i = 4; // not a VLA; OK to declare here
        f(i); // never called
//      int a[i]; // error: VLA cannot be declared here
    case 0:
        i = 17;
    default:
        int a[i]; // OK to declare VLA here
        printf("%d\n", i); // prints 17 if expr == 0, prints indeterminate value otherwise
}
(C99以降)

キーワード

switch case default

#include <stdio.h>
void func(int x)
{
   printf("func(%d): ", x);
   switch(x)
   {
      case 1: printf("case 1, ");
      case 2: printf("case 2, ");
      case 3: printf("case 3.\n"); break;
      case 4: printf("case 4, ");
      case 5:
      case 6: printf("case 5 or case 6, ");
      default: printf("default.\n");
   }
}
int main(void)
{
   for(int i = 1; i < 9; ++i) func(i);
}

出力:

func(1): case 1, case 2, case 3.
func(2): case 2, case 3.
func(3): case 3.
func(4): case 4, case 5 or case 6, default.
func(5): case 5 or case 6, default.
func(6): case 5 or case 6, default.
func(7): default.
func(8): default.

参考文献

  • C17規格 (ISO/IEC 9899:2018):
  • 6.8.4.2 switch文 (p: 108-109)
  • C11規格 (ISO/IEC 9899:2011):
  • 6.8.4.2 switch文 (p: 149-150)
  • C99規格 (ISO/IEC 9899:1999):
  • 6.8.4.2 switch文 (p: 134-135)
  • C89/C90標準 (ISO/IEC 9899:1990):
  • 3.6.4.2 switch文

関連項目

C++ ドキュメント for switch statement
翻訳の説明: - 「C++ documentation」→「C++ ドキュメント」と翻訳 - HTMLタグ、属性、 タグ内のテキストは保持 - 「switch statement」はC++専門用語として保持 - フォーマットと構造は完全に維持