1. 联合体1.1 联合体类型的声明像结构体一样联合体也是由一个或者多个成员构成这些成员可以不同的类型。但是编译器只为最大的成员分配足够的内存空间。联合体的特点是所有成员共用同一块内存空间。所以联合体也叫共用体。给联合体其中一个成员赋值其他成员的值也跟着变化#includestdio.h//联合类型的声明unionUn{charc;//占1字节inti;//占4字节};intmain(){//联合变量的定义unionUn un{0};//计算连个变量的⼤⼩printf(%zd\n,sizeof(un));return0;}1.2 联合体的特点联合的成员是共用同一块内存空间的这样一个联合变量的大小至少是最大成员的大小因为联合体至少得有能力保存最大的那个成员。先来看一段代码#includestdio.hunionUn{charc;//占1字节inti;//占4字节};intmain(){unionUn un{0};printf(%zd\n,sizeof(un));printf(%p\n,un);printf(%p\n,(un.i));printf(%p\n,(un.c));return0;}运行发现开辟了4个字节的空间 u 的地址/ u.i / u.c的地址是一样的 c 和 i 共用了一块空间 这样就导致对 c 修改会改变 i 对 i 修改也是同理因为他们共用了一块空间所以同一时间只能有效使用一个成员。总结一下联合体的特点1. 共用体大小 最大成员的大小本例为 4 字节2. 共用体所有成员共享同一块内存地址完全相同3. 同一时间只能有效使用一个成员1.3 相同成员的结构体和联合体对比结构体#includestdio.hstructS{charc;inti;};structSs{0};联合体#includestdio.hunionUn{chari;inti;};unionUn un{0};总结1.4 联合体大小的计算计数规则联合的大小至少是最大成员的大小。当最大成员大小不是最大对齐数的整数倍的时候就要对齐到最大对齐数的整数倍。#includestdio.hunionUn1{charc[5];//char类型占1字节 对齐数为1inti;//int类型占4字节 对齐数为4//联合的大小至少是最大成员(5)的大小//对齐到最大对齐数4的整数倍};unionUn2{shortc[7];//short类型占2字节 对齐数为2inti;//int类型占4字节 对齐数为4//联合的大小至少是最大成员(14)的大小//最大成员大小不是最大对齐数的整数倍的时候就要对齐到最大对齐数4的整数倍};intmain(){//下⾯输出的结果是什么printf(%d\n,sizeof(unionUn1));printf(%d\n,sizeof(unionUn2));return0;}联合体的一个练习写一个程序判断当前机器是大端还是小端我们在之前的章节中实现过这个代码现在来回顾一下#includestdio.hintcheck_sys(){intn1;return*(char*)n;}intmain(){intretcheck_sys();//小端返回1大端返回0if(ret1)printf(小端\n);elseprintf(大端\n);return0;}使用联合体实现#includestdio.hintcheck_sys(){unionUn{charc;inti;}u;u.i1;returnu.c;}intmain(){intretcheck_sys();//小端返回1大端返回0if(ret1)printf(小端\n);elseprintf(大端\n);return0;}在小端模式下整数 1 的低位字节0x01存储在低地址而 char c 读取的正是这个低地址字节因此返回 1在大端模式下整数 1 的高位字节0x00存储在低地址char c 读取的是 0因此返回 0核心巧妙之处利用联合体共享内存的特性c 和 i 共用开头 1 个字节给 i 赋值直接能通过 c 读到第一个字节的数据2. 枚举类型2.1 枚举类型的声明枚举顾名思义就是一个一个列举把可能值全部列举出来。比如一周的星期一到星期日是有限的7天可以⼀⼀列举性别有男、女、保密也可以一一列举月份有12个月也可以一一列举#includestdio.henumDay//星期{Mon,Tues,Wed,Thur,Fri,Sat,Sun};enumSex//性别{MALE,FEMALE,SECRET};enumColor//颜⾊{RED,GREEN,BLUE};以上定义的enum Day / enum Sex / enum Color都是枚举类型{ } 中的内容是枚举类型可能的取值也叫枚举常量。这些可能取值都是有值的默认从0开始依次递增1当然在声明枚举类型的时候也可以赋初值。enumColor//颜⾊{RED2,GREEN4,BLUE8};2.2 枚举类型的使用举例计算器菜单选择程序用枚举来表示菜单选项#includestdio.hvoidmenu(){printf(********************\n);printf(*** 1.add 2.sub ***\n);printf(*** 3.mul 4.div ***\n);printf(*** 0.exit ***\n);printf(********************\n);}enumOption{exit,//0add,//1sub,//2mul,//3div//4};intmain(){intinput0;printf(请选择);scanf(%d,input);switch(input){caseadd:// 直接用枚举名不用记数字break;casesub:break;casemul:break;casediv:break;caseexit:break;default:break;}return0;}枚举的优点1. 增加代码的可读性和可维护性2. 和#define定义的标识符比较枚举有类型检查更加严谨。3. 便于调试预处理阶段会删除#define 定义的符号4. 使用方便一次可以定义多个常量5. 枚举常量是遵循作用域规则的枚举声明在函数内只能在函数内使用