SUN = 5; 編譯錯誤。a = MON; ✓;a = 1; ✗(需強轉)。'MON' 或 "MON"。當必須從整數賦值時,使用枚舉類型強轉:
enum Weekday { SUN, MON, TUE, WED, THU, FRI, SAT };
enum Weekday d;
d = (enum Weekday)3; // 相當於 d = WED;
原理:將整數視為枚舉元素的序號(ordinal),而非元素本身的值。若枚舉有顯式賦值(如 RED=10),強轉 3 會找序號為 3 的元素,而非值為 3 的元素。
#include <stdio.h>
int main() {
enum Task { BACKUP, CLEAN_LOG, REPORT, CHECK_DB };
enum Task schedule[30]; // 30 天任務表
enum Task cur = BACKUP;
for (int day = 1; day <= 30; ++day) {
schedule[day-1] = cur;
cur = (cur == CHECK_DB) ? BACKUP : (enum Task)(cur + 1); // 循環輪換
}
for (int day = 1; day <= 30; ++day) {
const char *name[] = {"備份", "清理日誌", "生成報表", "檢查數據庫"};
printf("第%2d天: %s\n", day, name[schedule[day-1]]);
}
return 0;
}
enum State { IDLE, CONNECTING, CONNECTED, ERROR };
void handle_event(enum State *st, int event) {
switch (*st) {
case IDLE:
if (event == EVT_START) *st = CONNECTING;
break;
case CONNECTING:
if (event == EVT_SUCCESS) *st = CONNECTED;
else if (event == EVT_FAIL) *st = ERROR;
break;
case CONNECTED:
if (event == EVT_DISCONNECT) *st = IDLE;
break;
case ERROR:
if (event == EVT_RESET) *st = IDLE;
break;
}
}
優勢:編譯器可檢測 switch 是否覆蓋所有枚舉值(-Wswitch-enum),漏寫 case 直接報警,重構極其安全。
| 誤區 | 正確認知 |
|---|---|
| 枚舉變量可直接 scanf 輸入 | scanf 只識別整數,需讀入 int 再強轉賦值 |
| 枚舉元素可作位運算 | 除非顯式定義為 2 的冪次(位掩碼),否則無意義 |
| enum 等同於 #define 常量 | enum 有類型、有作用域、可調試符號表,#define 只是文本替換 |
| sizeof(enum) 總是 1 字節 | 取決於編譯器實現,通常為 int 大小(4 字節) |
枚舉看似簡單,實則是 C 語言類型系統與語義表達的橋樑。善用「只能賦枚舉常量、強轉整數序號、switch 全覆蓋檢查」三大特性,能讓狀態機、錯誤碼、配置選項等代碼既安全又自文檔化。