C ++包含许多内置数据类型。 但是对于我们想要做的事来说,这些类型有时并不够用。 因此,C ++允许程序员创建自己的数据类型。 这些数据类型称为用户定义数据类型。
也许最简单的用户定义数据类型就是枚举类型(Enumerated Types)。 枚举类型中每个可能的值都定义为符号常量(称为枚举器)。
一、为什么用枚举
在了解其语法之前,先看看枚举怎么个用途,是否有学的必要呢?其实枚举是很实用的一个工具,主要体现在代码阅读方面。
设想这样一个场景,一个项目,写了上千行,有些常量类型,只有几个固定的取值,在写的时候为了图方便,可以就用数字表示(如0,1,2,3),比如颜色,状态等。这样固然方便,且节省内存,但过了一个月再想看明白这个代码,就不容易了吧。
再退一步,拿颜色举例,有时要用上七八种颜色,如果用数字表示,对应起来也是极不方便,还得想半天,这时,如果颜色就用名字表示,但在内存中还是数字,就舒服得多了。
二、语法
1.定义
写程序时,我们常常需要为某个对象关联一组可选alternative属性.例如,学生的成绩分A,B,C,D等,天气分sunny, cloudy, rainy等等。
在C++中,枚举类型是通过enum关键字定义的,比如定义颜色类型:
enum Color { COLOR_BLACK, COLOR_RED, COLOR_BLUE, COLOR_GREEN = 9, COLOR_WHITE, COLOR_CYAN, COLOR_YELLOW, COLOR_MAGENTA, };
括号内为该类型所有可能的取值(枚举器),以逗号分隔;大括号结尾要有分号。
注意:因为枚举类型一旦定义,枚举器就相当于全局常量,所以一般枚举器的命名要有前缀且大写,以防止和其他变量名冲突。
2.使用
Color c1(COLOR_BLACK); Color c2 = COLOR_BLACK; Color c3 = COLOR_YELLOW; std::cout << c1 << endl; std::cout << c2 << endl; std::cout << c3 << endl;
以上代码输出0、2和12,因为默认情况下,枚举器的值依次为0,1,2…
当然也可以显式地定义各个枚举器的取值,当一个枚举器的值给定,下一个枚举器默认赋值加1。同时也可对两个枚举器给同样的取值,这时这两个枚举器是完全相同的,可以互换,仅仅名字不同。
三、其他用例
当需要表示一组特定的预定义状态时,枚举类型对于代码可读性而言非常有用。
例如,当函数内部发生错误时,函数通常将整数返回给调用方以表示错误代码。 通常,小的负数用于表示不同的可能的错误代码。例如:
int readFileContents() { if (!openFile()) return -1; if (!readFile()) return -2; if (!parseFile()) return -3; return 0; // success }
但是,使用像这样的数字经常让人云里雾里。 一种替代方法是通过使用枚举类型:
enum ParseResult { SUCCESS = 0, ERROR_OPENING_FILE = -1, ERROR_READING_FILE = -2, ERROR_PARSING_FILE = -3 }; ParseResult readFileContents() { if (!openFile()) return ERROR_OPENING_FILE; if (!readFile()) return ERROR_READING_FILE; if (!parsefile()) return ERROR_PARSING_FILE; return SUCCESS; }
这比使用整数返回值更容易阅读和理解。 在使用这个函数时,也将更为方便
if (readFileContents() == SUCCESS) { // do something } else { // print error message }
因为枚举数据类型的符号名称与整数值相关联,所以它们可以在 switch 语句中使用,如下面的程序所示,该程序还演示了可以使用枚举的数据类型,而不实际创建该类型的任何变量。
#include <iostream> using namespace std; // Declare the enumerated type enum Roster { Tom = 1, Sharon, Bill, Teresa, John }; // Sharon - John will be assigned default values 2-5. int main() { int who; cin >> who; switch (who) { case Tom : cout << "Tom's birthday is January 3.\n"; break; case Sharon : cout << "Sharon's birthday is April 22.\n"; break; case Bill : cout << "Bill's birthday is December 19.\n"; break; case Teresa : cout << "Teresa's birthday is February 2.\n"; break; case John : cout << "John's birthday is June 17.\n"; break; default : cout << "Invalid selection\n"; } return 0; }
最后,再提一句,我们常用的布尔类型,其实不过是枚举类型的一个特例,枚举类型在更大程度上丰富了布尔类型的用途。