自定义数据类型-枚举类型enum

一、枚举类型的概念

在实际编程中,经常会遇到变量的取值被限定在一个有限的、确定的范围内的情况。例如:

  • 一场比赛的结果只有胜、负、平、取消四种状态
  • 一个袋子里的球只有红、黄、蓝、白、黑五种颜色
  • 一个星期只有星期一、星期二至星期日七天

如果使用 int 或 char 来表示这些值(比如用 0~6 表示星期几),编译器无法阻止程序将 8 这样的非法值赋给变量,存在安全隐患。

C++ 的枚举类型(enum)就是专门为解决这类问题而设计的。它将变量所有可能的取值范围一一列举出来,此后该类型的变量只能取列举出的值,增强了代码的可读性和类型安全性。

二、枚举类型的声明形式

enum 枚举类型名 {枚举元素列表};

示例:

enum Weekday {SUN, MON, TUE, WED, THU, FRI, SAT};
enum GameResult {WIN, LOSE, DRAW, CANCEL};
enum BallColor {RED, YELLOW, BLUE, WHITE, BLACK};

三、枚举元素的值

1. 默认赋值规则

枚举元素在声明时如果没有显式指定值,编译器会自动从 0 开始依次赋值。

enum Weekday {SUN, MON, TUE, WED, THU, FRI, SAT};
枚举元素默认值
SUN0
MON1
TUE2
WED3
THU4
FRI5
SAT6
2. 显式指定值

可以在声明时手动为枚举元素指定值,后面未指定的元素依次在前一个值的基础上加 1。

enum Weekday {SUN = 7, MON = 1, TUE, WED, THU, FRI, SAT};
枚举元素值
SUN7
MON1
TUE2
WED3
THU4
FRI5
SAT6
3. 注意事项
  • 枚举元素的值在编译期确定,不能对枚举元素进行赋值操作。例如 SUN = 0; 是不合法的。
  • 多个枚举元素可以具有相同的值。
  • 枚举元素的作用域与枚举类型本身的作用域一致。

四、枚举变量的定义与使用

1. 定义枚举变量
Weekday today;          // 定义 Weekday 类型的变量
GameResult result;      // 定义 GameResult 类型的变量Code language: JavaScript (javascript)

也可以在声明枚举类型的同时定义变量:

enum Weekday {SUN, MON, TUE, WED, THU, FRI, SAT} today, tomorrow;
2. 枚举变量的赋值

枚举变量只能被赋值为该枚举类型中定义的枚举元素,不能直接赋值为整数。

today = MON;        // 正确
// today = 1;      // 错误:不能将 int 直接赋给枚举变量Code language: JavaScript (javascript)

如果确实需要将整数转换为枚举值,必须进行强制类型转换:

today = Weekday(3); // 正确:将 3 强制转换为 Weekday 类型,等价于 WEDCode language: JavaScript (javascript)
3. 枚举值的关系运算

枚举值可以进行关系运算(比较大小),比较时实际比较的是它们对应的整数值。

if (today == WED) { ... }
if (MON < FRI) { ... }   // 比较的是 1 < 5Code language: JavaScript (javascript)

五、代码示例

以下代码演示了枚举类型的各种用法:

#include <iostream>
using namespace std;

int main()
{
    // 示例1:基本枚举类型
    enum Weekday {SUN, MON, TUE, WED, THU, FRI, SAT};
    Weekday today = WED;
    cout << "today = " << today << endl;   // 输出 3

    // 示例2:显式指定枚举值
    enum Weekday2 {SUNDAY = 7, MONDAY = 1, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, SATURDAY};
    Weekday2 d = SUNDAY;
    cout << "d = " << d << endl;            // 输出 7

    // 示例3:枚举变量的赋值与输出
    Weekday day1 = MON;
    Weekday day2 = FRI;
    cout << "day1 = " << day1 << ", day2 = " << day2 << endl;   // 输出 1 和 5

    // 示例4:枚举的关系运算
    if (day1 < day2)
        cout << "MON comes before FRI" << endl;

    // 示例5:枚举在 switch 语句中的使用
    Weekday d2 = SAT;
    switch (d2)
    {
    case MON: cout << "Monday" << endl; break;
    case TUE: cout << "Tuesday" << endl; break;
    case WED: cout << "Wednesday" << endl; break;
    case THU: cout << "Thursday" << endl; break;
    case FRI: cout << "Friday" << endl; break;
    case SAT: cout << "Saturday" << endl; break;
    case SUN: cout << "Sunday" << endl; break;
    }

    // 示例6:整数强制转换为枚举
    int n = 4;
    Weekday d3 = Weekday(n);   // 强制转换,n=4 对应 THU
    cout << "d3 = " << d3 << endl;

    // 示例7:比赛结果枚举
    enum GameResult {WIN, LOSE, DRAW, CANCEL};
    GameResult r = WIN;
    cout << "Game result: " << r << endl;   // 输出 0

    // 示例8:枚举元素的值
    enum Color {RED, GREEN, BLUE = 10, YELLOW, CYAN = 15, MAGENTA};
    cout << "RED=" << RED << " GREEN=" << GREEN << " BLUE=" << BLUE;
    cout << " YELLOW=" << YELLOW << " CYAN=" << CYAN << " MAGENTA=" << MAGENTA << endl;
    // 输出:RED=0 GREEN=1 BLUE=10 YELLOW=11 CYAN=15 MAGENTA=16

    // 示例9:枚举作为循环变量
    for (Weekday w = SUN; w <= SAT; w = Weekday(w + 1))
    {
        cout << w << " ";
    }
    cout << endl;

    // 示例10:声明时定义变量
    enum Season {SPRING, SUMMER, AUTUMN, WINTER} current = AUTUMN;
    cout << "current season = " << current << endl;   // 输出 2

    return 0;
}Code language: PHP (php)

六、注意事项

  • 枚举元素不是字符串,不能直接用 cout 输出其名称。输出时得到的是对应的整数值。如需输出名称,需借助 switch 语句或映射表。
  • 枚举变量的取值范围理论上可以存储任意整数,但只有赋值为枚举元素或经过强制转换的值才有明确意义。
  • 枚举类型占用内存大小通常等于 int 的大小,但具体由编译器决定。
  • 枚举元素之间不能重名。如果不同枚举类型中有相同名称的元素,需通过枚举类型名区分(在 C++11 强类型枚举 enum class 中解决)。
  • 不能直接将整数赋给枚举变量,也不能直接将枚举变量赋给整数类型变量(需要强制转换)。但枚举变量可以隐式转换为整数参与运算。

七、C++11 强类型枚举(enum class)

C++11 引入了强类型枚举(枚举类),解决了传统枚举的命名冲突和隐式转换问题:

enum class Weekday {SUN, MON, TUE, WED, THU, FRI, SAT};
Weekday d = Weekday::MON;   // 必须用作用域运算符
// int x = d;               // 错误:不能隐式转换
int x = static_cast<int>(d); // 正确:显式转换Code language: PHP (php)

强类型枚举的优点:

特性传统 enumenum class
作用域枚举元素暴露在枚举所在作用域枚举元素限定在枚举类型内
隐式转换可隐式转换为 int不能隐式转换为 int
底层类型由编译器决定可显式指定,如 enum class Color : char { … }

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注