枚举和联合体

时间:2022-09-05 21:30:51

枚举

什么是枚举?

枚举是一种用户定义的数据类型,它用关键字 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;
}

输出结果为:

枚举和联合体

需要说明的是,本程序的第35行代码,只是定义了一个数据类型,并没有定义变量,该数据类型为 enum WeekDay 

而之所以输出是06,是因为枚举中的元素是从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;
}

输出结果为:

枚举和联合体

为什么要使用枚举?

在回答这个问题前。先要说的一个概念是常量符号化,所谓常量符号化,即用符号而不是具体的数字来表示程序中的数字,这个可以使用constdefine实现,但是一个个的constdefine相对繁琐,而枚举在此处有些便利之处,因为枚举元素一般按常量处理

如例1enum量如果是使用constdefine表示,则是这样

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,值则依次从n。如:enum colors { red, yellow, green } ; 就创建了三个常量,red的值是0yellow1,⽽而green2。当需要⼀一些可以排列起来的常量值时,定义枚举的意义就是给了这些常量值名字。

枚举类型可以跟上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 dataa.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;
}

输出结果为:

枚举和联合体

141516行不会报错


【所有代码均在windows系统下dev c++下运行通过】

(如有错误,敬请指正)