为何要用枚举类型
【History】 由宏定义演化而来,相当于整型常量的宏定义(参见History of enums in C and C++http://www.ibm.com/developerworks/rational/library/scoped-enums/ )。
何时要用枚举类型
避免使用不易理解的数字,用有意义的标识来替代。涉及物理状态或者含有物理意义的常量,不应直接使用数字,必须用有意义的枚举或宏来代替。
——华为C语言编程规范4-2
l 定义有意义的整型常量
l 需要对一系列具象事物予以自然数作为标号时
枚举类型有什么用
l 变量的取值被限定为有限个
l 增强可读性
怎么使用枚举类型
enum 枚举名{ 枚举值表 }【可以添加定义的变量】;
详细如下:
声明的结构:
[tag] // tag 枚举名,后文要使用时,缺省则以后不可引用(无名枚举)
{
[
枚举常量 1[ =常量表达式],
枚举常量 2[ =常量表达式],
枚举常量 3[ =常量表达式],
...
//枚举定义表(花括号内内容)中的枚举定义用逗号间隔,而不是分号,
// 这一点注意与结构体区别
]
枚举常量n[ =常量表达式] // C99中最后一个枚举定义可以有逗号,标准C不可以 (默认不用)
}
[枚举变量 1,枚举变量 2,...] //声明中可以同时定义枚举变量(类型为枚举类型的变量)
;
引用的结构:
定义枚举变量:
enum tag 枚举变量 1,枚举变量 2,...;
可用做强制转换 ( enum tag)
l []方括号内内容为可以缺省的;
l ...为重复内容;
l 以上的写法说明参考《C参考手册》一书,书中的表述方式不够简单,不便阅读,因此没有直接引用。
使用的技巧
和结构体类型一样,为了省去写struct,enum这些类型说明符的麻烦,一般在作为接口的头文件中通过typedef定义枚举类型,以简化后面的调用。
typedef enum 枚举名{ 枚举值表 } 枚举的新命名;
实例说明
typedef enum
{
KEY_ADD,
KEY_SUB,
KEY_PREV,
KEY_NEXT,
KEY_OK,
KEY_CANCEL,
KEY_MAX
}KEY_e;
l C89标准最后一个枚举值后面不加逗号,C99允许逗号,为了兼容,建议按标准C写,即不带最后一个逗号
l 枚举值为常量,标识符推荐用大写,并且推荐有共同的前缀表明其来源隶属
l KEY_MAX得到枚举值表的枚举定义的个数,而并不是可用的枚举元素,便于定义数组l 推荐在新的枚举名后面添加_e后缀表示enum枚举类型 (e取enum的首字母)。
l 对于typedef新定义的类型名,推荐添加 _t后缀(typedef的首字母),这里加了_e后缀就不用再后缀_t了
【 _t后缀】我们在Codewarrior PE的PE_type.h中可以看到以下的代码:
typedef signed char int8_t;
# endif
------------------------------------------------------我是分割线------------------------------------------------------
注意:
1.同一个程序中不能定义同名的枚举类型,
2.不同的枚举类型中也不能存在同名的命名常量。
enum的本质是define的集合体。
故满足:
1.本质是定义常量
2.满足集合体的要求:不能重复申明变量名,不能重复申明元素。
关于sizeof(enum):
1.联合体中unit存在内存对齐(struct)
2.sizeof(enum)在32bit机器上,总等于4byte:因为对于枚举变量名,只是一个逻辑值,即指针指向这个名字,故指针类型为4byte;而对于具体的enum变量,由于对应的值是long类型,故sizeof(long)=4byte
枚举型的元素值可以重复:
int main(){
enum {
mon,
tue,
wed,
thu=0,
fri,
sat=(unsigned long)1234567890,
sun
} a1,a2,a3,a4,a5,a6,a7;
root@audit:/home/sjw/test# ./test_snum
a1=0 a2=1 a3=2 a4=0 a5=1 a6=1234567890 a7=1234567891
------------------------------------------------------我是分割线-------------------------------------------------------
定义:
注意1:如果要定义两个具有同样特性枚举类型的变量,可以有如下的两种定义方式:
enum Box{pencil,pen}; //声明枚举类型Box;
enum Box box1,box2; //定义枚举变量box1,box2;
再有一种定义方式就是在声明枚举类型的同时进行定义:
enum {pencil,pen} box1, box2;
对于枚举变量中的枚举元素,系统是按照常量来处理的,所以枚举元素又叫枚举常量;它们是不能进行普通的算数赋值运算的,也就是说它们的值是不能被改变的,
注意2:如果你不对枚举变量中的枚举元素进行赋值操作,那么枚举元素将会被系统自动从0开始递增,第一个枚举元素的值为0,第二个枚举元素的值为1,第三个枚举元素的值为2,等等,依次类推;如果你为枚举类型中的一个枚举元素赋了值,而没有为其余枚举元素赋值,那么系统对下一个枚举元素的赋值操作将是把上一个枚举元素的值加1得到;后面的以此类推;而第一个枚举元素仍然是从0开始,直到你赋初值的那个元素之前的元素为止;
注意3:对枚举变量来说,是不能直接赋值的,所以,对枚举变量是赋元素操作,而不能直接赋整数值;要把整数值赋给枚举变量,那么必须先把整数值的类型强制转换成对应的枚举类型;
但是这里的赋值类型是long:
centos 6.5:
root@audit:/home/sjw/test# gcc -o ./test_snum ./test_snum.c
./test_snum.c: In function 鈓ain?
./test_snum.c:11: warning: integer constant is too large for 鈒ong?type
root@audit:/home/sjw/test# ./test_snum
a1=505 a2=506 a3=507 a4=-700 a5=-699 a6=1234567890 a7=1234567891