枚举
什么是枚举?
枚举是一种用户定义的数据类型,它用关键字 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++下运行通过】
(如有错误,敬请指正)