前言
enum枚举用于创建符号常量,通常用来替代const创建符号常量的方式。
定义枚举
一般有两种定义枚举的方式,第一种是设置枚举名,第二种是不设置枚举名(匿名)。
enum color {red, green, blue}; // 第一种
enum {red, green, blue}; // 第二种
其中,color
是枚举名;red, green, blue
是枚举量,默认从0开始,即:red = 0,green = 1,blue = 2。
事实上,此时此刻的color就是一个数据类型了,可以利用它声明或定义变量——当然,没有枚举名也可以做到:
color skin; // 利用枚举名声明变量skin,如果没有初始值,默认初始值为0
enum {red, green, blue} skin; // 匿名枚举名 声明变量方式
赋值规则
对枚举类型的变量赋值时,规定只能用枚举量。对skin来说,赋值只能用red,green,blue。只不过,也可以通过强制转换实现赋值(不建议)。
color skin = blue;
// 等同于
color skin = color(2);
尽管枚举量是整型,但直接把整型数字赋给枚举变量是错误的行为:
color skin = 2; // 错误
编译器报错:error: invalid conversion from ‘int’ to ‘color’
。
对枚举来说,只定义了赋值运算符,没有定义算术运算。
color skin = red; // 正确,允许此赋值方式
skin++; // 错误,枚举类型没有加法运算
skin = 2 + red; // 错误,为什么错误后面再说
枚举量可以被提升(隐式转换)为int类型(反之不可以):
int skin = red; // 正确,但注意,现在的skin是int型,因此red被隐式转换成了int型
skin = red + green; // 正确,因为red和green都被隐式的转换成了int型,因此可以相加
skin = green + 12; // 正确
但下面的操作是错误:
color skin = red + blue; // 错误
这是因为red和blue都被提升为了int型,二者相加的结果自然也是int,然而skin是枚举变量,不可以被int赋值。
枚举设值
枚举量默认从0开始,但也可以手动的设置枚举量的值,常用方法有以下三种:
显示地定义全部枚举量的值:
enum {red = 5, green = 1, blue = 2};
显示地定义部分枚举量的值,此时没有定义值的枚举量会基于前一个值加1:
enum {red = 5, green = 0, blue}; // 此时red = 5,green = 0, blue = 1
允许存在多个值相同的枚举量:
enum {red = 0, green = 1, blue = 1};
事实上,枚举量不仅可以是int型,也可以是long、long long类型。
取值范围
尽管可以通过强制类型转换使得任意整型都可以赋值给枚举型变量——仅仅看上去是这样而已,但事实不是。枚举类型的变量有默认的取值范围。
- 最大值:首先找到枚举量中最大的值,包含这个值的最小的2的幂 - 1 就是该枚举类变量允许的最大值。如上述中的
enum {red = 5, green = 1, blue = 2};
,最大值为5,那么包含5的最小2的幂是8,再减1,得到7。允许最大值是7。 - 最小值:如果枚举量中,最小值不小于0,那么允许最小值为0。如果最小值小于0,则取这个值的绝对值,利用求最大值的方法求解,对最后的解加上负号。即,假如枚举中最小值为-6,则允许最小值是-7。
说明:枚举的取值范围是我在《C++ Primer Plus》上看到的,然而经过测试,发现真实的运行结果并未受到取值范围约束。理论上最大只能取值7的时候,我对其赋值1000也没问题。难道是作者错了吗?
——事实上,我更愿意相信,取值范围的规定是为了让程序更“鲁棒”。所谓“君子不立墙角之下”,可行之事不代表可靠,作为程序员,你应该尽量不让程序处于危险之中。
还不快抢沙发