根據整數運算式的值,允許在多個程式碼區段中選取範圍。
語法
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
備註
根據 condition
的值,switch
陳述式會導致控制項傳輸至在其陳述式本文中的一個 labeled-statement
。
condition
必須有整數型別,或是具有明確轉換成整數型別的類別型別。 整數升階會如標準轉換中所述來進行。
switch
陳述式正文由一系列 case
標籤和一個可選 default
標籤組成。 labeled-statement
是下列其中一個標籤和後方的陳述式。 有標記的陳述式不是語法需求,但是 switch
陳述式沒有它們就沒有意義。 case
陳述式中沒有任何兩個 constant-expression
值評估為相同的值。 default
標籤只能顯示一次。 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) );
}
在上述範例中,如果 uppercase_A
是大寫 c
,則遞增 '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
值的數量。 此數目會受到可用記憶體的限制。