C 枚举、联合体
C 枚举
1. 基本概念
枚举是 C 语言中的一种基本数据类型,它可以让数据更加简洁明了。
enum 枚举名 {枚举元素1, 枚举元素2, 枚举元素3, ...}
当然也可以采用宏定义的方式来定义常量,比如定义一个星期的天数:
#define MON 1
#define TUE 2
#define WED 3
#define THU 4
#define FRI 5
#define SAT 6
#define SUN 7
这样会显得代码量很多,用枚举的方式就会是这样,所以枚举更简洁一点。
enum DAY
{
MON=1, TUE, WED, THU, FRI, SAT, SUN
};
注意:第一个枚举成员的默认值为整型的 0,后续枚举成员的值在前一个成员上加 1。在上面这个实例中把第一个枚举成员的值定义为 1,第二个就为 2,以此类推。
可以在定义枚举类型时改变枚举元素的值:
enum season {spring, summer=3, autumn, winter};
没有指定值的枚举元素,其值为前一元素加 1。也就说 spring 的值为 0,summer 的值为 3,autumn 的值为 4,winter 的值为 5
2. 枚举变量的定义
前面我们只是声明了枚举类型,接下来我们看看如何定义枚举变量。
我们可以通过以下三种方式来定义枚举变量
- 先定义枚举类型,再定义枚举变量
enum DAY
{
MON=1, TUE, WED, THU, FRI, SAT, SUN
};
enum DAY day;
- 定义枚举类型的同时定义枚举变量
enum DAY
{
MON=1, TUE, WED, THU, FRI, SAT, SUN
} day;
- 省略枚举名称,直接定义枚举变量
enum
{
MON=1, TUE, WED, THU, FRI, SAT, SUN
} day;
C 联合体
1. 基本概念
联合体又叫共用体,它是一种特殊的数据类型,虽然和结构体很相似,但它们有本质的区别:结构体的各个成员是各自独立的,它们的内存位置是不同的,但联合体却是在相同的内存位置存储不同的数据类型。
2. 定义联合体
联合体的定义跟结构体很相似。
union tag {
member-list
member-list
member-list
...
} variable-list ;
- tag 是联合体标签。
- member-list 是标准的变量定义,可以说有效的数据类型定义。
- variable-list 联合体变量,定义在联合体的末尾,最后一个分号之前,可以指定一个或多个变量结构。
- 在一般情况下,tag、member-list、variable-list 这 3 部分至少要出现 2 个。
union tag 是可选的,每个 member definition 是标准的变量定义,比如 int i; 或者 float f; 或者其他有效的变量定义。在联合体定义的末尾,最后一个分号之前,您可以指定一个或多个联合体变量,这是可选的。
定义一个名为 Data 的共用体类型,有三个成员 x、y 和 z:
union Data
{
int x;
char y;
double z;
} data;
现在,Data 类型的变量可以存储一个整数、一个浮点数,或者一个字符。这意味着一个变量(相同的内存位置)可以存储多个多种类型的数据。
3. 初始化及访问联合体成员
- 初始化联合体成员
// 普通初始化:第一个成员有效(即只有100是有效的,其余成员会被覆盖)
union Data at = {100, 'k', 3.14};
// 指定成员初始化:最后一个成员有效(即只有3.14是有效的,其余成员会被覆盖)
union Data at = {
.x = 100,
.y = 'k',
.z = 3.14,
}
- 访问联合体成员
访问共用体的成员,跟结构体一样需要使用成员访问运算符(.)。但由于联合体特殊的存储特性,不管怎么初始化和赋值,最终都是只有一个成员是有效的。
at.x = 100;
at.y = 'k';
at.z = 3.14; // 只有最后一个赋值的成员有效
printf("%d\n", at.x);
printf("%c\n", at.y);
printf("%lf\n", at.z);
- 联合体指针
union Data *p = &at;
p->x = 100;
p->y = 'k';
p->z = 3.14; // 只有最后一个赋值的成员有效
printf("%d\n", p->x);
printf("%c\n", p->y);
4. 联合体的使用
联合体很少去单独去使用,常以结构体成员的形式存在,用来表达某种互斥的属性。
union Data
{
int x;
char y;
double z;
};
struct node
{
int a;
char b;
double c;
union Date at; // at内有三种互斥的属性,非此即彼
};
int main(int argc, char *argv[])
{
struct node n;
n.at.x = 100;
}