前言
这篇博客就把剩下的两个自定义类型联合体和枚举好好总结一下,让我们好好看看联合体和枚举到底是什么
个人主页:小张同学zkf
若有问题 评论区见
感兴趣就关注一下吧
目录
1. 联合体
1.1 联合体类型的声明
1.2 联合体的特点
1.3 相同成员的结构体和联合体对比
1.4 联合体大小的计算
2. 枚举类型
2.1 枚举类型的声明
2.2 枚举类型的优点
2.3 枚举类型的使用
1. 联合体
1.1 联合体类型的声明
# include <stdio.h>// 联合类型的声明union Un{char c;int i;};int main (){// 联合变量的定义union Un un = { 0 };// 计算连个变量的⼤⼩printf ( "%d\n" , sizeof (un));return 0 ;}
输出结果:4
由图可见他们俩共处一个空间,所以字节长度为最大的类型int
1.2 联合体的特点
# include <stdio.h>// 联合类型的声明union Un{char c;int i;};int main (){// 联合变量的定义union Un un = { 0 };un.i = 0x11223344 ;un.c = 0x55 ;printf ( "%x\n" , un.i);return 0 ;}
输出结果:11223355
由图可知是将最低位由于联合体的特点,覆盖成c的55。
那我们想一下,既然c和i共处一室,它们的地址会一样吗?
我们试一下
# include <stdio.h>// 联合类型的声明union Un{char c;int i;};int main (){// 联合变量的定义union Un un = { 0 };// 下⾯输出的结果是⼀样的吗?printf ( "%p\n" , &(un.i));printf ( "%p\n" , &(un.c));printf ( "%p\n" , &un);return 0 ;}
输出结果:
001 AF85C001 AF85C001 AF85C
可见输出结果一样,这也就说明联合体地址和里面每个成员名的地址是一样的
1.3 相同成员的结构体和联合体对比
struct S{char c;int i;};struct S s = { 0 };union Un{char c;int i;};union Un un = { 0 };
联合体相较于结构体可以节省空间,但是它会出现成员与成员覆盖的情况
1.4 联合体大小的计算
我们了解了联合体在内存中的布局,那联合体的字节大小到底怎么计算那
我们首先要知道:
# include <stdio.h>union Un1{char c[ 5 ];int i;};union Un2{short c[ 7 ];int i;};int main (){// 下⾯输出的结果是什么?printf ( "%d\n" , sizeof ( union Un1));printf ( "%d\n" , sizeof ( union Un2));return 0 ;}
我们先分析un1,根据前面博客分析的结构体而言,char的最大对齐数是1,int的最大对齐数为4,所以这个联合体的最大对齐数为4,联合体至少也是最大成员的空间,成员中最大的空间是char c[5],为5,5不是4的倍数,所以对齐到8的位置,就是8;再看un2,un2至少为14个字节吧,short和int的对齐数分别为2和4,所以最大对齐数为4,14不是4的倍数,所以要对齐到16的位置,大小为16。
我们认识了联合体,那我们是不是又有一种巧妙的方式判断大小端了
int check_sys (){union{int i;char c;}un;un.i = 1 ;return un.c; // 返回 1 是⼩端,返回 0 是⼤端}
既然char成员占据低地址处的位置,那此时i为1,返回c,正好可以直接判断这个位置上的数字。
2. 枚举类型
枚举是 C 语言中的一种基本数据类型,用于定义一组具有离散值的常量
2.1 枚举类型的声明
一周的星期一到星期日是有限的7天,可以一 一列举性别有:男、女、保密,也可以⼀⼀列举月份有12个月,也可以⼀⼀列举三原色,也是可以一 一列举
这些数据的表示就可以使用枚举了。
enum Day // 星期{Mon,Tues,Wed,Thur,Fri,Sat,Sun};enum Sex // 性别{MALE,FEMALE,SECRET} ;enum Color // 颜⾊{RED,GREEN,BLUE};
这些可能取值都是有值的,默认从0开始,依次递增1,当然在声明枚举类型的时候也可以赋初值。
比如:
enum Color // 颜⾊{RED= 2 ,GREEN= 4 ,BLUE= 8};
若不赋初值
enum Color // 颜⾊{RED ,//0GREEN ,//1BLUE//2};
那里面的常量值就默认从0开始依次加一
若中间赋初值
enum Color // 颜⾊{RED ,//0GREEN ,//1BLUE=8,//8YELLOW//9};
可见刚开始不赋初值的时候,依然从零开始依次加一,从哪开始赋初值,就从这个初值的基础上依次加一。
2.2 枚举类型的优点
这时肯定有人会想定义常量的话,那我们可以用#define宏定义呀,为什么会有枚举这东西那
相比#define枚举可以调试,而#define在调试时会直接在预处理阶段替换。
我们来看一下枚举的优点就知道了
枚举的优点:1. 增加代码的可读性和可维护性2. 和#define定义的标识符比较枚举有类型检查,更加严谨。3. 便于调试,预处理阶段会删除 #define 定义的符号4. 使用方便,一次可以定义多个常量5. 枚举常量是遵循作用域规则的,枚举声明在函数内,只能在函数内使用
2.3 枚举类型的使用
enum Color // 颜⾊{RED= 1 ,GREEN= 2 ,BLUE= 4};enum Color clr = GREEN;
结束语
枚举和联合体总结完了,这两个和上一篇的结构体都可以用typedef关键字重命名,好了全部自定义类型总结完了
OK,感谢观看