枚举和联合体

时间:2022-09-05 21:31:09

枚举

什么是枚举?

枚举是一种用户定义的数据类型,它用关键字 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++下运行通过】

(如有错误,敬请指正)