switch?面對「單一變數、多個離散值、不同處理」的多路選擇,if-else if 鏈條冗長且易誤。switch 提供結構化、可優化(跳躍表)的替代方案。
switch (表達式) {
case 常數值1:
語句群1;
break;
case 常數值2:
語句群2;
break;
...
default:
語句群默認;
break;
}
| 規則 | 說明 |
|---|---|
| 表達式型別 | 必須為整數型別(char、int、enum),不可為浮點數/字串 |
| case 標籤 | 必須為編譯期常數(字面值或常數表達式),不可為變數 |
| case 唯一性 | 同一 switch 內 case 值不得重複 |
| 貫穿特性 | 無 break 時自動執行下一 case,直到遇到 break 或結束 |
default | 可選,無匹配 case 時執行,位置任意(習慣放最後) |
| 大括號 | case/default 後的語句群不需大括號包裹 |
#include
int main(void) {
for (int test = 0; test <= 10; ++test) {
switch (test) {
case 1: case 2: case 3: // 合併 case
printf("Small: %d\n", test);
break;
case 5:
printf("Five\n");
break;
default:
puts("Other");
}
}
return 0;
}
#include
#include
int main(void) {
char c;
puts("Press A/B, ESC to quit");
while ((c = getch()) != 27) {
switch (c) {
case 'A': case 'a':
puts("Action A triggered");
break;
case 'B': case 'b':
puts("Action B triggered");
break;
default:
puts("Unknown key");
}
}
return 0;
}
switch (month) {
case 1: case 3: case 5: case 7: case 8: case 10: case 12:
days = 31; break;
case 4: case 6: case 9: case 11:
days = 30; break;
case 2:
days = isLeapYear(year) ? 29 : 28; break;
}
default 做防禦性檢查
switch (status) {
case OK: handleOk(); break;
case ERROR: handleError(); break;
default:
logError("Invalid status: %d", status); // 捕獲未預期值
abort();
}
switch(編譯器可警告漏寫 case)
typedef enum { RED, GREEN, BLUE } Color;
void printColor(Color c) {
switch (c) {
case RED: puts("Red"); break;
case GREEN: puts("Green"); break;
case BLUE: puts("Blue"); break;
// 無 default,編譯器 -Wall 會警告漏寫 enum 值
}
}
case 1: {
int temp = compute(); // 變數生命週期限制在 case 區塊
use(temp);
break;
}
case 值連續且範圍小 → 編譯器生成跳躍表,O(1) 分派case 值稀疏/範圍大 → 編譯器退化為二分搜尋或條件鏈| 錯誤 | 後果 | 修正 |
|---|---|---|
忘記 break | 非預期貫穿 | 習慣每個 case 寫 break,故意貫穿加註解 /* fallthrough */ |
case 用變數 | 編譯錯誤 | 改用 if-else 或預先映射為常數 |
| 浮點數作表達式 | 編譯錯誤 | 乘以倍數轉整數,或改用 if-else |
重複 case 值 | 編譯錯誤 | 檢查邏輯合併 |
switch 是 C 語言處理離散值多路分派的標準工具。掌握「整數/字元表達式、常數 case、貫穿機制、default 防禦、列舉配合」五大核心,並養成「每 case 必 break、漏寫 case 靠編譯器檢查」的習慣,能寫出既高效又可維護的選擇邏輯。記住:當 case 超過 10 個或需範圍判斷時,改用 if-else 或查表法更清晰。