首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> 關於C語言

C 語言 switch 語句完全指南:語法、穿透、最佳實踐與效能優化

     編輯:關於C語言

基本語法


switch (整數表達式) {
    case 常量表達式1: 
        語句序列1; 
        break; // 關鍵:跳出 switch
    case 常量表達式2:
        語句序列2;
        break;
    default: // 可選:無匹配時執行
        語句序列默認;
}
  • 控制表達式:必須為**整數類型** (`int`, `char`, `enum`, `short`, `long`)。**不可為浮點數/字串/結構體**。
  • case 標籤:必須為**整數常量表達式** (編譯期確定),唯一,不可重複。
  • default:最多一個,位置任意 (慣例放最後)。

核心機制:穿透

若 `case` 無 `break` (或 `return`/`goto`/`throw`),執行流**直接落入下一個 `case`/`default`**,直到遇到 `break` 或 `switch` 結束。


switch (ch) {
    case 'a': case 'e': case 'i': case 'o': case 'u':
    case 'A': case 'E': case 'I': case 'O': case 'U':
        printf("母音\n"); break; // 多標籤共用代碼:合法且常用
    case 'b': ... break;
    default: printf("其他\n");
}

有意穿透註釋**:`/* fallthrough */` (C17 `[[fallthrough]]` 屬性 / GCC `-Wimplicit-fallthrough` 需註釋抑制警告)。

進階用法

1. 字元分類


char c = getchar();
switch (c) {
    case '0'...'9': puts("數字"); break; // GCC 擴展:範圍 case (非標準)
    // 標準寫法需多 case 或 if-else
    case 'a': case 'b': ... case 'z':
    case 'A': ... case 'Z': puts("字母"); break;
    default: puts("其他");
}

2. 列舉類型 (編譯器可檢查覆蓋率)


enum Color { RED, GREEN, BLUE };
void paint(enum Color c) {
    switch (c) {
        case RED:   puts("Red"); break;
        case GREEN: puts("Green"); break;
        case BLUE:  puts("Blue"); break;
        // 無 default,若新增枚舉值編譯器會警告 (-Wswitch-enum)
    }
}

3. 編譯器優化:跳躍表 vs 二分查找

  • 稠密 case 值** (如 0~100):編譯器生成**跳躍表** (Jump Table),O(1) 分發,極快。
  • 稀疏 case 值** (如 1, 1000, 10000):編譯器生成**二分查找**決策樹或 if-else 鏈,O(log n)。
  • 建議**:熱路徑 `switch` 盡量使用連續/稠密整數 (或 `enum`),獲得最佳效能。

switch vs if-else 鏈

特性switchif-else
判斷類型整數/枚舉任意布爾表達式
比較方式等值比較任意關係/邏輯運算
效能 (多分支)跳躍表 O(1) / 二分 O(log n)線性 O(n) 順序求值
可讀性 (多常量值)高低
範圍判斷不支援 (標準)支援

常見錯誤與避坑

  1. 忘記 `break`** → 非預期穿透 (最大坑)。
  2. case 非常量** → 編譯錯誤 (`case x:` 變數不行)。
  3. 重複 case 值** → 編譯錯誤。
  4. 控制表達式為浮點/字串** → 編譯錯誤。
  5. 變數聲明在 case 內** → 需用 `{}` 包裹作用域 (C89 要求聲明在塊開頭)。

現代最佳實踐

  • **枚舉配合 `switch`** 實現狀態機/命令分發,開啟 `-Wswitch-enum` 確保覆蓋率。
  • **`default` 必寫**:處理未預期值,防禦性編程 (記錄日誌/斷言/安全模式)。
  • **有意穿透加註釋** `/* fallthrough */` 或 `[[fallthrough]]` (C23/C++17)。
  • **避免過大 `switch`** (超過百個 case) → 改用函數指針陣列/哈希表/狀態模式。
  • **字串匹配** → 不要用 `switch` (不支援),用 `strcmp` 鏈、完美哈希 (gperf)、Trie 樹或哈希表。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved