列舉型別核心概念
列舉 讓變數只能取預先定義的有限值集合。適用場景:星期、月份、狀態碼、錯誤代碼、選單選項等「窮盡所有可能值」的領域。
宣告與定義語法
// 1. 先宣告後定義
enum Weekday { Sun, Mon, Tue, Wed, Thu, Fri, Sat };
enum Weekday today, tomorrow;
// 2. 同時宣告定義
enum Weekday { Sun, Mon, Tue, Wed, Thu, Fri, Sat } today, tomorrow;
// 3. 匿名列舉 (僅定義變數)
enum { Sun, Mon, Tue, Wed, Thu, Fri, Sat } today, tomorrow;
// 4. 指定底層整數值
enum Status { OK = 0, ERROR = -1, TIMEOUT = -2 };
enum Bool { FALSE = 0, TRUE = 1 };
列舉常數特性
| 特性 | 說明 | 範例 |
| 本質是常數 | 不可修改,Sun = 5 編譯錯誤 | 編譯期確定 |
| 隱含整數值 | 預設從 0 遞增 | Sun=0, Mon=1, ..., Sat=6 |
| 可手動指定值 | 任意整數,可重複 | enum {A=1, B=1, C=3} → A=1,B=1,C=3 |
| 部分指定自動遞增 | 未指定者 = 前一值 + 1 | enum {X=10, Y, Z} → X=10,Y=11,Z=12 |
| 型別安全性 | C 弱型別,可隱性轉 int | int i = Sun; 合法 |
實戰程式碼範例
#include
#include
int main() {
enum Egg { A, B, C }; // A=0, B=1, C=2
enum Egg test = A; // 正確賦值方式
// test = 1; // 警告:整數隱性轉換
// test = (enum Egg)1; // 強制轉換:合法但不推薦
switch (test) {
case A: printf("test 是 A\n"); break;
case B: printf("test 是 B\n"); break;
case C: printf("test 是 C\n"); break;
}
// C++ 風格展示
#ifdef __cplusplus
enum Egg2 { A2, B2, C2 };
Egg2 test2 = C2;
if (test2 == C2) cout << "C++ 判斷成功" << endl;
if (test2 == 2) cout << "整數比較也成立" << endl;
cout << A2 << "|" << B2 << "|" << test2 << endl; // 0|1|2
#endif
return 0;
}
進階應用:狀態機與位元遮罩
1. 有限狀態機
enum State { IDLE, CONNECTING, CONNECTED, ERROR };
void handle_event(enum State *state, enum Event evt) {
switch (*state) {
case IDLE:
if (evt == EVT_START) *state = CONNECTING;
break;
case CONNECTING:
if (evt == EVT_SUCCESS) *state = CONNECTED;
else if (evt == EVT_FAIL) *state = ERROR;
break;
// ...
}
}
2. 列舉作為位元旗標
enum Permissions {
READ = 1 << 0, // 0x01
WRITE = 1 << 1, // 0x02
EXEC = 1 << 2, // 0x04
ADMIN = 1 << 3 // 0x08
};
int user_perm = READ | WRITE; // 0x03
if (user_perm & EXEC) { /* 可執行 */ }
3. 字串化列舉值 (除錯用)
const char* state_str(enum State s) {
switch (s) {
case IDLE: return "IDLE";
case CONNECTING: return "CONNECTING";
// ...
default: return "UNKNOWN";
}
}
C / C++ / Java 比較
| 特性 | C (enum) | C++ (enum class) | Java (enum) |
| 型別安全 | 弱 (隱性轉 int) | 強 (需強制轉換) | 強 (完整類別) |
| 命名空間 | 全域汙染 | Scoped (State::IDLE) | 類別內 |
| 可攜帶方法 | 否 | 是 (C++11) | 是 |
| 可實作介面 | 否 | 否 | 是 |
| 底層型別 | int (實作定義) | 可指定 (int/short/char) | 固定 int |
最佳實踐建議
- 命名規範:列舉型別用單數 PascalCase (
enum Color),常數用全大寫底線 (RED)
- 明確賦值:序列化/網路傳輸時務必指定數值,避免編譯器調整導致不相容
- 避免隱性轉換:使用
switch 而非 if (state == 1)
- 預留擴充值:
enum {V1=1, V2=2, RESERVED=100, V3=101}
- C++ 專案優先用
enum class 獲得型別安全
結語
列舉型別將「魔術數字」轉化為「有語意的常數」,是提升程式碼可讀性、維護性與型別安全的關鍵工具。掌握其宣告變體、自動遞增規則、位元旗標技巧與跨語言差異,能讓你在系統設計、協定定義、狀態機實作中遊刃有餘。
- 上一篇文章: C 語言聯合體 用法完整指南:宣告、記憶體共享與實戰技巧
- 下一篇文章: Objective-C 自訂事件實作:基於 UIControl 事件機制的跨類別通訊
Copyright ©
程式碼之家 All Rights Reserved