枚举

1、什么是枚举
枚举是一种创建常量符号的方式,相较于#define预处理,枚举更加简洁,故而其为#define的替代品。
可以理解为其为数值起了一个别名(标识符),多个相同数值可以有不同多个别名。
同时枚举还可以用来定义新类型:

enum S { a, b, c, d};//enum 枚举名 {枚举成员};
enum S tmp;	//创建一个S类型的变量tmp
tmp = a;

如上,S为枚举,其中的集合元素a b c d 为符号常量,又称之为枚举量(枚举成员);
若不为枚举量赋值,则最开始的枚举量a默认值为0,其后按序依次加1,即b为1;
若创建枚举量时对其赋初值如:b=100,c=122。则a=0,d=123。

enum大致用法类似struct结构体。
通常枚举类型可以作为函数参数传参,因为其被限制为只能传入对应的枚举成员。有效避免了传入无关参数。

2、如何使用枚举

  • 除了使用上述方法来声明枚举变量外,还可以如下定义声明同时进行:
enum S { a, b, c, d}T;

对应枚举变量T还可以进行赋初值:

enum S { a, b, c, d}T=a;

实际效果与tmp等同。

  • 使用typedef关键字将枚举类型定义为别名
typedef enum S
{
	a,
	b,
	c,
	d
} s;

其中s为枚举型enum S的别名,使用为:s tmp;(等价为enum )

  • int转换为枚举类型需要强制转换
enum S tmp;
tmp = S(3);

反之若将枚举类型赋值给int类型则不需要,其会发生自动转换。
若是对一个不在范围内的int强制转换为枚举类型,结果会是不确定的。
如S(4)不为任何一个枚举量。
这意味着这样做不会出错,但不能依赖得到的结果。

  • 枚举相加
enum S tmp;
tmp = a+b;//不合法

如上代码将导致错误,对于枚举,其只定义了赋值运算符,没有定义算数运算。
a+b看似无法执行,但其发生了自动转换,转为int相加。
因为两者类型不匹配,int无法直接赋值给枚举类型,这将导致类型错误。

而以下代码是合法的:

int ans;
ans = a+b;

这是因为a和b可自动被提升为整型,发生了类型转换,结果为int相加。

  • 若不用来定义新类型可以省略掉枚举名S
enum {a, b, c, d};

以上只用来创建符号常量。
可以将变量tmp放到}与;中间,来创建枚举变量

  • 避免创建相同的枚举量或枚举类型名
    遵守单一定义原则,避免重定义。

3、枚举的取值范围
当然对于枚举来说只有其内部指明的枚举量对应的数值才是有效的,但是由于int类型的强制转换增加了可赋给枚举量的合法值。
其上限为:枚举量的最大值对应最小2的幂-1;
其下限为:若枚举量最小值不小于0则为0,否则寻找方法与上限类似。
即先去符号找到对应幂-1,再添回负号。
[-6, 101]对应的取值范围为:[-7, 127];

4、枚举的大小
通常而言有编译器决定,取值范围小则使用一个字节或更少,含long则使用4个字节。
也就是说,一个枚举类型大小不会超过4个字节,即一个int整型大小。
实际上,一个枚举类型所占空间的大小即为一个常数所占内存空间的大小,即一个int整型所占空间大小。
使用sizeof计算,枚举类型大小为4个字节。