枚举
什么是枚举?
枚举是一种用户定义的数据类型,它用关键字 enum 以如下语法来声明: enum 枚举类型名字 {名字0, …, 名字n} ;
简单的说,就是把一个事物的可能的结果一一列举出来
怎样使用枚举?
下面举个例子
例1:
# include <stdio.h> enum WeekDay { Monday, Tuesday, Wednesday, Thursday, Friday, Saturday, Sunday }; int main(void) { enum WeekDay day1, day2; day1 = Monday; day2 = Sunday; printf("Monday = %d\n", day1); printf("Sunday = %d\n", day2); return 0; }
输出结果为:
需要说明的是,本程序的第3到5行代码,只是定义了一个数据类型,并没有定义变量,该数据类型为 enum WeekDay
而之所以输出是0和6,是因为枚举中的元素是从0开始依次递增的,当然,如果指定元素的值,其后的元素依旧会依次递增下去,示例如下
例2:
# include <stdio.h> enum WeekDay { Monday = 1, Tuesday, Wednesday = 7, Thursday, Friday, Saturday, Sunday }; int main(void) { enum WeekDay day1, day2, day3, day4; day1 = Monday; day2 = Tuesday; day3 = Wednesday; day4 = Sunday; printf("Monday = %d\n", day1); printf("Tuesday = %d\n", day2); printf("Wednesday = %d\n", day3); printf("Sunday = %d\n", day4); return 0; }
输出结果为:
为什么要使用枚举?
在回答这个问题前。先要说的一个概念是常量符号化,所谓常量符号化,即用符号而不是具体的数字来表示程序中的数字,这个可以使用const和define实现,但是一个个的const和define相对繁琐,而枚举在此处有些便利之处,因为枚举元素一般按常量处理
如例1的enum量如果是使用const或define表示,则是这样
int const Monday = 0; int const Tuesday = 1; int const Wednesday = 2; int const Thursday = 3; int const Friday = 4; int const Saturday = 5; int const Sunday = 6;
或
# define Monday 0 # define Tuesday 1 # define Wednesday 2 # define Thursday 3 # define Friday 4 # define Saturday 5 # define Sunday 6
枚举类型名字通常并不真的使用,要用的是在大括号里的名字,因为它们就是就是常量符号,它们的类型是int,值则依次从0 到n。如:enum colors { red, yellow, green } ; 就创建了三个常量,red的值是0,yellow是1,⽽而green是2。当需要⼀一些可以排列起来的常量值时,定义枚举的意义就是给了这些常量值名字。
枚举类型可以跟上enum作为类型,但是实际上是以整数来做内部计算和外部输入输出的
枚举的优缺点
虽然枚举类型可以当作类型使⽤用,但是实际上 很少(不好)用,如果有意义上排比的名字,用枚举比const int方便,枚举比宏(macro)好,因为枚举有int类型
如果想要对枚举元素计数,则可在正常定义的枚举元素后加一个表示有用的元素个数,例如,enum color{ red, yellow, green, blue, purple, Num };,Num的值为5,其可以表示这个枚举中有效元素的个数,在对枚举元素进行遍历等操作时,就可以用到这个
联合体(也叫共用体)
关键字为union,其所有的成员共享一个内存空间,同一时间只有一个成员是有效的,其大小即其所占内存最大的成员所占的内存
其格式与结构体相似,可以这样定义——
union data { int i; char c; } a, b, c;
也可以这样——
union data { int i; char c; }; union data a, b, c;
还可以这样——
union { int i; char c; }a, b, c;
这与结构体表面上是一样的类型
下面举几个例子
例3:
# include <stdio.h> union data { int i; char c; } a; int main(void) { a.i = 3; a.c = 'A'; //A的ASCLL值是65 printf("%d\n", a.i); printf("a.i的地址为:%p\na.c的地址为:%p\n", &a.i, &a.c); return 0; }
输出结果为:
由结果可以更好地理解上面的话,最终输出的是a.c,所以说,同一时间只有一个成员是有效的;而最终输出的union data和a.i的地址相同,也证明了“其大小即其所占内存最大的成员所占的内存”这句话的正确
还有就是,联合体不能作为函数的参数,也不能作为函数的返回类型,这点是和结构体不一样的,不过,依旧可以使用指向联合体变量的指针(与结构体变量的用法类似),并且它也可以出现在结构体中,还可以定义联合体数组,当然,结构体和数组也可以出现在联合体中
例4:
# include <stdio.h> # include <stdlib.h> union data { int i; char c; } a, * p; int main(void) { int s, k = 1; char ch = 'A'; union data t[3]; p = (union data *)malloc(sizeof(union data)); p->i = 10; p->c = 'A'; for (s=0; s<3; s++) { t[s].i = k++; t[s].c = ++ch; } for (s=0; s<3; s++) { printf("%d ", t[s].c); } return 0; }
输出结果为:
14、15、16行不会报错
【所有代码均在windows系统下dev c++下运行通过】
(如有错误,敬请指正)