switch
ステートメント (C++)
整数式の値に応じてコードの複数のセクション間を切り替えます。
構文
selection-statement
=
switch
(
init-statement
optC++17condition
)
statement
init-statement
=
expression-statement
simple-declaration
condition
=
expression
attribute-specifier-seq
optdecl-specifier-seq
declarator
brace-or-equal-initializer
labeled-statement
=
case
constant-expression
:
statement
default
:
statement
注釈
switch
ステートメントを指定すると、 の値に応じて、ステートメント本体の 1 つの condition
labeled-statement
にコントロールが転送されます。
condition
は整数型を持つか、整数型への明確な変換を持つクラス型である必要があります。 「標準変換」で説明されているように整数の上位変換が実行されます。
switch
ステートメントの本体は、一連の case
ラベルと省略可能な default
ラベルで構成されます。 labeled-statement
は、これらのラベルのいずれかと、それに続くステートメントです。 ラベル付きステートメントは構文上の要件ではありませんが、それらがないと switch
ステートメントを使用する意味がありません。 case
ステートメント内の 2 つの constant-expression
値が同じ値に評価されてはなりません。 default
ラベルは 1 回だけ指定できます。 default
ステートメントは、多くの場合末尾に置かれますが、switch
ステートメント本体内の任意の場所に置くことができます。 case
または default
ラベルは、 switch
ステートメント内でのみ使用できます。
各 case
ラベルの constant-expression
は、condition
と同じ型の定数値に変換されます。 その後、condition
と等しいかどうか比較されます。 condition
の値に一致する case
constant-expression
値の後、制御は最初のステートメントに渡されます。 結果の動作を次の表に示します。
switch
ステートメントの動作
状態 | アクション |
---|---|
変換後の値は、上位変換された制御式の値と一致します。 | 制御は、そのラベルの次のステートメントに移ります。 |
定数のいずれも case ラベル内の定数と一致しない。default ラベルが存在する。 |
制御は default ラベルに移動します。 |
定数のいずれも case ラベル内の定数と一致しない。default ラベルが存在しない。 |
制御は switch ステートメントの後のステートメントに移動します。 |
一致する式が見つかった場合、実行は後の case
ラベルや default
ラベルを通して続行できます。 break
ステートメントは、実行を停止し、switch
ステートメントの後のステートメントに制御を移すために使用されます。 break
ステートメントがない場合は、一致する case
ラベルから switch
ステートメントの最後までのすべてのステートメントが、default
句も含めて実行されます。 次に例を示します。
// switch_statement1.cpp
#include <stdio.h>
int main() {
const char *buffer = "Any character stream";
int uppercase_A, lowercase_a, other;
char c;
uppercase_A = lowercase_a = other = 0;
while ( c = *buffer++ ) // Walks buffer until NULL
{
switch ( c )
{
case 'A':
uppercase_A++;
break;
case 'a':
lowercase_a++;
break;
default:
other++;
}
}
printf_s( "\nUppercase A: %d\nLowercase a: %d\nTotal: %d\n",
uppercase_A, lowercase_a, (uppercase_A + lowercase_a + other) );
}
上の例では、c
が大文字の 'A'
である場合、uppercase_A
をインクリメントします。 uppercase_A++
の後の break
ステートメントによって switch
ステートメント本体の実行が終了し、制御が while
ループに移ります。 break
ステートメントを使用しない場合、実行は次のラベル付きステートメントに "フォール スルー" され、lowercase_a
と other
もインクリメントされます。 case 'a'
の break
ステートメントも、同様の目的で使用しています。 c
が小文字の 'a'
である場合、lowercase_a
がインクリメントされ、break
ステートメントによって switch
ステートメントの本体が終了します。 c
が 'a'
でも 'A'
でもない場合は、default
ステートメントが実行されます。
Visual Studio 2017 以降 (/std:c++17
モード以降で使用可能): [[fallthrough]]
属性は C++17 標準で指定されます。 これを switch
ステートメント内で使用できます。 これは、コンパイラ、またはコードを読む人に対して、フォールスルー動作が意図的であることを示すヒントです。 現在、Microsoft C++ コンパイラでは、フォールスルー動作に関する警告は行わないので、この属性はコンパイラの動作に影響しません。 次の例では、終了されないラベル付きステートメント内の空のステートメントに、この属性が適用されます。 つまり、セミコロンは必要です。
int main()
{
int n = 5;
switch (n)
{
case 1:
a();
break;
case 2:
b();
d();
[[fallthrough]]; // I meant to do this!
case 3:
c();
break;
default:
d();
break;
}
return 0;
}
Visual Studio 2017 バージョン 15.3 以降 (/std:c++17
モード以降で使用可能): switch
ステートメントに、セミコロンで終わる init-statement
句を含めることができます。 これにより変数が導入されて初期化されます。そのスコープは switch
ステートメントのブロックに制限されます。
switch (Gadget gadget(args); auto s = gadget.get_status())
{
case status::good:
gadget.zip();
break;
case status::bad:
throw BadGadget();
};
switch
ステートメントの内部ブロックには、定義と初期化子を含めることができます ("到達可能" である (すべての可能な実行パスで回避されない) 限り)。 これらの宣言を使用して導入された名前にはローカル スコープがあります。 次に例を示します。
// switch_statement2.cpp
// C2360 expected
#include <iostream>
using namespace std;
int main(int argc, char *argv[])
{
switch( tolower( *argv[1] ) )
{
// Error. Unreachable declaration.
char szChEntered[] = "Character entered was: ";
case 'a' :
{
// Declaration of szChEntered OK. Local scope.
char szChEntered[] = "Character entered was: ";
cout << szChEntered << "a\n";
}
break;
case 'b' :
// Value of szChEntered undefined.
cout << szChEntered << "b\n";
break;
default:
// Value of szChEntered undefined.
cout << szChEntered << "neither a nor b\n";
break;
}
}
switch
ステートメントは入れ子にすることもできます。 入れ子にすると、case
ラベルや default
ラベルは、そのすぐ外側の switch
ステートメントと関連付けられます。
Microsoft 固有の動作
Microsoft C++ では、switch
ステートメント内の case
値の数が制限されません。 この数は、使用できるメモリによってのみ制限されます。
関連項目
フィードバック
https://aka.ms/ContentUserFeedback」を参照してください。
以下は間もなく提供いたします。2024 年を通じて、コンテンツのフィードバック メカニズムとして GitHub の issue を段階的に廃止し、新しいフィードバック システムに置き換えます。 詳細については、「フィードバックの送信と表示