C++ 中 enum 语法
C++ 中 enum
语法全面介绍
在 C++ 中,enum
(枚举)是一种用户定义的类型,用于将一组命名的整数常量组合在一起。它提供了一种创建具有明确语义的符号化常量的方式,使代码更易读、更安全。以下是 C++ 中 enum
的详细语法和用法:
一、基础枚举(Traditional Enum)
1. 定义语法
enum 枚举名 {枚举常量1,枚举常量2,枚举常量3 = 特定值, // 可选赋值...
};
2. 示例
// 定义枚举类型表示颜色
enum Color {RED, // 默认为0GREEN, // 默认为1BLUE = 5, // 显式赋值为5YELLOW // 自动为6(BLUE+1)
};// 定义枚举类型表示方向
enum Direction {UP, // 0DOWN, // 1LEFT, // 2RIGHT // 3
};
3. 关键特性
- 隐式整数转换:枚举常量会隐式转换为整数,默认从
0
开始依次递增。 - 显式赋值:可以为枚举常量显式指定整数值,后续常量会在此基础上递增。
- 作用域:枚举常量位于枚举类型的作用域中(例如
Color::RED
)。
二、枚举类(Enum Class,C++11 引入)
为解决传统枚举的作用域和类型安全问题,C++11 引入了枚举类(也称为强类型枚举)。
1. 定义语法
enum class 枚举名 {枚举常量1,枚举常量2,枚举常量3 = 特定值,...
};
2. 示例
// 定义枚举类表示四季
enum class Season {SPRING, // 默认为0SUMMER, // 1AUTUMN, // 2WINTER // 3
};// 定义枚举类表示网络状态(显式赋值)
enum class NetworkStatus {DISCONNECTED = 100,CONNECTING = 101,CONNECTED = 102,ERROR = 200
};
3. 关键特性
- 强类型:枚举类的常量属于不同的类型,不能与其他类型隐式转换。
- 作用域:枚举常量位于枚举类的作用域中(例如
Season::SPRING
)。 - 类型安全:不允许与整数直接比较,需显式转换。
- 底层类型指定:可以指定枚举的底层类型(默认是
int
):enum class Flags : uint32_t {FLAG1 = 1,FLAG2 = 2,FLAG3 = 4 };
三、枚举的使用方式
1. 声明变量
// 传统枚举
Color myColor = RED; // 正确
Color yourColor = Color::BLUE; // 推荐写法(显式作用域)// 枚举类
Season currentSeason = Season::SUMMER;
NetworkStatus status = NetworkStatus::CONNECTED;
2. 枚举与整数的转换
-
传统枚举:可以隐式转换为整数,也可以从整数隐式转换:
int code = RED; // 正确,code=0 Color c = static_cast<Color>(2); // 正确,c=GREEN(假设GREEN=1,则此例为非法值)
-
枚举类:必须显式转换为整数,从整数转换也需显式转换:
int s = static_cast<int>(Season::AUTUMN); // s=2 Season s2 = static_cast<Season>(3); // s2=WINTER(需确保值合法)
3. 枚举的作用域解析
enum E1 { A, B };
enum E2 { A, C }; // 合法,A属于不同枚举的作用域int main() {E1 e = A; // 错误:A的作用域不明确E1 e1 = E1::A; // 正确E2 e2 = E2::A; // 正确
}
四、枚举在代码中的应用场景
1. 状态机
如 LeetCode 65 题中的状态定义:
enum State {STATE_INITIAL,STATE_INT_SIGN,STATE_INTEGER,// ... 其他状态
};
- 优势:用符号化的状态名替代魔法数字,提高代码可读性。
2. 选项标志
enum class Permissions {NONE = 0,READ = 1,WRITE = 2,EXECUTE = 4
};
- 用法:通过位运算组合权限:
Permissions userPerm = Permissions::READ | Permissions::WRITE;
3. 接口参数规范化
enum class SortOrder {ASCENDING,DESCENDING
};void sortArray(std::vector<int>& arr, SortOrder order) {// 根据order执行不同排序逻辑
}
- 优势:确保参数只能是合法值,避免无效输入。
五、C++11 枚举的增强特性
1. 枚举类的前向声明
enum class Direction; // 前向声明枚举类
2. 底层类型指定
enum class SmallEnum : uint8_t {A, B, C
}; // 底层类型为uint8_t,节省内存
3. 枚举类的作用域严格性
枚举类的常量不会污染外围作用域,避免命名冲突。
六、传统枚举与枚举类的对比
特性 | 传统枚举 (enum) | 枚举类 (enum class) |
---|---|---|
作用域 | 常量位于外围作用域 | 常量位于枚举类的作用域中 |
类型安全 | 可与整数隐式转换,可能不安全 | 需显式转换,类型安全 |
命名冲突 | 可能与其他枚举常量冲突 | 因作用域隔离,避免冲突 |
前向声明 | 支持 | 支持 |
底层类型指定 | 不支持(C++11前) | 支持 |
七、枚举使用的最佳实践
- 优先使用枚举类:除非需要与旧代码兼容,否则使用
enum class
以获得更好的类型安全和作用域控制。 - 命名规范:枚举类型名使用驼峰式(如
NetworkStatus
),枚举常量使用全大写(如CONNECTED
)。 - 避免魔法数字:用枚举常量替代代码中的硬编码整数。
- 显式赋值:若需要枚举常量对应特定整数值,显式赋值以避免依赖默认递增。
- 合理使用底层类型:对取值范围小的枚举,指定较小的底层类型(如
uint8_t
)以节省内存。
八、枚举在 LeetCode 65 题中的应用
在有效数字验证的状态机中,枚举用于定义不同的处理阶段:
enum State {STATE_INITIAL, // 初始状态STATE_INT_SIGN, // 整数符号位STATE_INTEGER, // 整数部分STATE_POINT, // 左侧有整数的小数点STATE_POINT_WITHOUT_INT, // 左侧无整数的小数点STATE_FRACTION, // 小数部分STATE_EXP, // 指数符号STATE_EXP_SIGN, // 指数符号后的符号位STATE_EXP_NUMBER, // 指数部分的整数// STATE_END (示例中未使用,可用于结尾状态)
};
- 每个状态对应数值字符串处理的一个阶段,通过状态转移表实现逻辑跳转,使代码逻辑清晰可维护。
通过掌握 enum
的语法和特性,可以在 C++ 中编写出更规范、更易读的代码,尤其是在状态机、选项标志等场景中。