跳转到内容

C++ 编程

来自维基教科书,开放的书籍,为开放的世界

enum 关键字用于创建一个名为 name 的枚举类型,该类型包含 name-list 中的元素。var-list 参数是可选的,可用于在声明时创建该类型的实例。

语法
    enum name {name-list} var-list;

例如,以下代码创建了所需的数据类型

enum card_suit {Clubs,Diamonds,Hearts,Spades};
card_suit first_cards_suit=Diamonds;
card_suit second_cards_suit=Hearts;
card_suit third_cards_suit=0; //Would cause an error, 0 is an "integer" not a "card_suit" 
card_suit forth_cards_suit=first_cards_suit; //OK, they both have the same type.

这行代码创建了一个新的数据类型 "card_suit",它只能取四个可能的值之一:"Clubs"、"Diamonds"、"Hearts" 和 "Spades"。一般来说,enum 命令采用以下形式

enum new_type_name { possible_value_1,
                     possible_value_1,
                     /* ..., */
                     possible_value_n
} Optional_Variable_With_This_Type;

而第二行代码创建了一个具有此数据类型的新变量,并将其初始化为 Diamonds 的值。其他行创建了此新类型的其他变量,并展示了一些可能的(和不可能的)初始化。

在内部,枚举类型存储为整数,从 0 开始,每增加一个新的可能数据类型值就增加 1。

enum apples { Fuji, Macintosh, GrannySmith };
enum oranges { Blood, Navel, Persian };
apples pie_filling = Navel; //error can't make an apple pie with oranges.
apples my_fav_apple = Macintosh;
oranges my_fav_orange = Navel; //This has the same internal integer value as my_favorite_apple

//Many compilers will produce an error or warning letting you know your comparing two different quantities.
if(my_fav_apple == my_fav_orange) 
  std::cout << "You shouldn't compare apples and oranges" << std::endl;

虽然枚举类型不是整数,但在某些情况下会转换为整数。例如,当我们尝试将枚举类型发送到标准输出时。

例如

enum color {Red, Green, Blue};
color hair=Red;
color eyes=Blue;
color skin=Green;
std::cout << "My hair color is " << hair << std::endl;
std::cout << "My eye color is " << eyes << std::endl;
std::cout << "My skin color is " << skin << std::endl;
if (skin==Green)
  std::cout << "I am seasick!" << std::endl;

将产生以下输出

My hair color is 0
My eye color is 2
My skin color is 1
I am seasick!

我们可以通过引入一个包含我们枚举类型名称的数组来改进此示例,例如

std::string color_names[3]={"Red", "Green", "Blue"};
enum color {Red, Green, Blue};
color hair=Red;
color eyes=Blue;
color skin=Green;
std::cout << "My hair color is " << color_names[hair] << std::endl;
std::cout << "My eye color is " << color_names[eyes] << std::endl;
std::cout << "My skin color is " << color_names[skin] << std::endl;

在这种情况下,hair 在作为索引数组时会自动转换为整数。此技术与颜色 Red 在内部存储为 "0",Green 在内部存储为 "1",而 Blue 在内部存储为 "2" 的事实密切相关。小心! 可以覆盖这些默认的枚举类型内部值的选项。

这可以通过在 enum 中简单地设置值来完成,例如

enum color {Red=2, Green=4, Blue=6};

事实上,没有必要为枚举类型的每个值设置整数。在这种情况下,编译器将简单地将前一个可能值的数值增加 1。

考虑以下示例

enum colour {Red=2, Green, Blue=6, Orange};

这里,"Red" 的内部值为 2,"Green" 的内部值为 3,"Blue" 的内部值为 6,"Orange" 的内部值为 7。在使用此功能时要小心,因为内部值不需要是唯一的。

在算术表达式中,枚举类型也会自动转换为整数。这使得能够为枚举类型的内部表示选择特定的整数变得很有用。

可以为标准计算机屏幕的宽度和高度枚举。这可以使程序执行有意义的计算,同时仍然保持枚举类型的优点。

enum screen_width {SMALL=800, MEDIUM=1280};
enum screen_height {SMALL=600, MEDIUM=768};
screen_width MyScreenW=SMALL;
screen_height MyScreenH=SMALL;
std::cout << "The number of pixels on my screen is " << MyScreenW*MyScreenH << std::endl;

需要注意的是,枚举类型中使用的内部值是常量,在程序执行过程中无法更改。

也许值得注意的是,虽然枚举类型可以转换为整数以便进行算术运算,但它们无法进行迭代。

例如

enum month { JANUARY=1, FEBRUARY, MARCH, APRIL, MAY, JUNE, JULY, AUGUST, SEPTEMBER, OCTOBER, NOVEMBER, DECEMBER};

for( month cur_month = JANUARY; cur_month <= DECEMBER; cur_month=cur_month+1)
{
  std::cout << cur_month << std::endl;
}

这将无法编译。问题在于 for 循环。循环中的前两个语句没有问题。我们可以创建一个新的 month 变量并对其进行初始化。我们还可以比较两个月,在这种情况下,它们将作为整数进行比较。我们不能递增 cur_month 变量。"cur_month+1" 的计算结果为整数,该整数可能无法存储到 "month" 数据类型中。

在上面的代码中,我们可以尝试通过替换 for 循环来修复这个问题

for( int monthcount = JANUARY; monthcount <= DECEMBER; monthcount++)
{
  std::cout << monthcount  << std::endl;
}

这将有效,因为我们可以递增整数 "monthcount"。

华夏公益教科书