22-联合体与枚举
文章目录
- 22-联合体与枚举
- 一、 联合体
- 1.1 定义和特点
- 1.2 语法
- 1.3 示例
- 1.4 联合体的使用
- 1.5 联合体的使用:检查系统的字节序
- 二、 枚举
- 2.1 定义和特点
- 2.2 语法
- 2.3 枚举常量的值可以手动修改
一、 联合体
1.1 定义和特点
联合体(Union)与结构体(Struct)在语法上非常相似,但它们在内存布局和使用方式上有显著的不同:
- 结构体:每个成员都有独立的内存空间,各成员可以同时存在,互不影响。
- 联合体:所有成员共享同一个内存空间,任意时刻只有一个成员是有效的。
联合体的每个成员公用同一个内存空间,因此也被称为共同体。联合体的尺寸取决于其最宽的成员。
1.2 语法
union 联合体标签 {
成员1;
成员2;
成员3;
// 其他成员
};
1.3 示例
#include <stdio.h>
union node {
int i;
char c;
short s;
double d;
};
int main(int argc, char const *argv[]) {
union node data;
printf("size: %ld\n", sizeof(data));
printf("i: %p\n", &data.i);
printf("c: %p\n", &data.c);
printf("s: %p\n", &data.s);
printf("d: %p\n", &data.d);
return 0;
}
空间:
输出:
注意事项:
- 联合体的尺寸取决于其最宽的成员。
- 联合体中所有成员的内存地址(首地址)是相同的。
- 任意时刻,只有一个成员是有效的,给某个成员赋值会使其他成员失效。
1.4 联合体的使用
联合体一般较少使用,更多时候是作为结构体的一部分,用来描述互斥的数据。
#include <stdio.h>
#include <string.h>
typedef struct demo {
char Name[32];
union {
char Type; // S 学生, T 老师, F 打饭阿姨, Q 清洁工
float num; // 成绩
int i; // 手抖值
char c; // 清洁能力
} stat;
} Node;
int main(int argc, char const *argv[]) {
Node data[3];
// 清洁工
strncpy(data[0].Name, "Even", 32);
data[0].stat.Type = 'Q';
data[0].stat.c = 'A';
// 学生
strncpy(data[1].Name, "Jacy", 32);
data[1].stat.Type = 'S';
data[1].stat.num = 13.86;
// 打饭阿姨
strncpy(data[2].Name, "CuiHua", 32);
data[2].stat.Type = 'F';
data[2].stat.i = 13;
for (size_t i = 0; i < 3; i++) {
switch (data[i].stat.Type) {
case 'Q':
printf("当前输出为清洁工:\n名字:%s\t人猿类型:%c\t清洁能力:%c\n",
data[i].Name, data[i].stat.Type, data[i].stat.c);
break;
case 'S':
printf("当前输出为学生:\n名字:%s\t人猿类型:%c\t学习能力:%f\n",
data[i].Name, data[i].stat.Type, data[i].stat.num);
break;
case 'F':
printf("当前输出为打饭阿姨:\n名字:%s\t人猿类型:%c\t抖肉能力:%d\n",
data[i].Name, data[i].stat.Type, data[i].stat.i);
break;
}
}
return 0;
}
1.5 联合体的使用:检查系统的字节序
可以使用联合体来检查系统是大端(Big-endian)还是小端(Little-endian):
小端序:
#include <stdio.h>
int check_endianness() {
union {
int i;
char c[sizeof(int)];
} u;
u.i = 1;
return u.c[0] == 1;
}
int main() {
if (check_endianness()) {
printf("Little-endian\n");
} else {
printf("Big-endian\n");
}
return 0;
}
或者是:
二、 枚举
2.1 定义和特点
枚举(Enumeration)是一种特殊的整型变量,枚举常量列表定义了一组有意义的整型常量。枚举本质上一种范围受到限制的整型,比我们可以使用 0 - 3 表示4种状态(比如某个硬件的状态:打开、运行、暂停、关闭)
2.2 语法
enum 枚举标签 { 常量1, 常量2, 常量3, 常量4 };
示例:
#include <stdio.h>
enum MIC { open, run, stop, close };
int main(int argc, char const *argv[]) {
enum MIC stat = run;
switch (stat) {
case open:
printf("麦克风状态为打开:%d\n", open);
break;
case run:
printf("麦克风状态为运行中:%d\n", run);
break;
case stop:
printf("麦克风状态为暂停:%d\n", stop);
break;
case close:
printf("麦克风状态为关闭:%d\n", close);
break;
}
return 0;
}
2.3 枚举常量的值可以手动修改
enum MIC { open, run = 5, stop, close };
注意:
- 枚举常量默认从0开始,后续常量依次递增。
- 枚举的本质是整型,可以进行所有整型操作。
- 枚举提高了代码的可读性和可维护性。