枚举?联合?拿捏了
《清明》 杜牧
清明时节雨纷纷,路上行人欲断魂。
借问酒家何处有?牧童遥指杏花村。
文章目录
- 前言
- 一.概念
-
- 1.枚举
- 2.联合
- 二.为什么要用枚举和联合
-
- 1.枚举的优点
- 2.联合的优点
- 三.枚举、联合使用实例
-
- 1.枚举变量注意事项
- 2.联合实现判断大小端
- 3.联合大小的计算
- 四.几道经典例题
-
- 1.枚举
- 2.联合
- 总结
前言
我们已经学习了结构体的基本知识,
现在来学一学其他数据形式。
一.概念
1.枚举
枚举顾名思义就是一一列举。
把可能的值一一列举。
比如我们现实生活中:
周一到周日,可以一一列举。
一年十二个月,可以一一列举。
如我们创建枚举变量Day,不进行赋值。
enum Day{Monday,Tuesday,Wednesday,Thursday,Friday,Saturday,Sunday};
若我们在enum里对周三赋值,即 Wednesday = 5;
则周四变为5后面一个数6,周五、周六同理。
2.联合
联合,又称为共用体。
联合是一种是一种特殊的自定义类型,包含一系列成员变量,特征是这些成员共用一块空间。
共用是如何体现的呢?
我们执行以下代码:
union Un{char c;//1int i;//4};int main(){union Un u;printf("%p\n", &u);//打印联合体地址printf("%p\n", &(u.c));//打印c的地址printf("%p\n", &(u.i));//打印i的地址}
我们发现各成员的地址是一样的。
这说明联合确实具有“共用”的特点。
我们用图像来进一步理解。
这时候细心的小伙伴就发现了。这不行呀!要是改了其中一个,另一个不也遭殃了吗?
但倒也不必慌张,因为在同一时间,我们只用其中一个,这样即使更改了,也不会有任何影响。
比方说,我们描述一个人的职业,在同一时间,我们只说他是老师,不会说他是老师,又说他是学生。
Tips:
联合的成员是共用一块内存空间的,这样一个联合变量的大小,最小是最大成员的大小。
二.为什么要用枚举和联合
1.枚举的优点
1.增加代码的可读性和可维护性
2.和#define定义的标识符相比,有类型检查,便于调试
3.防止了命名污染
4.使用方便,一次性定义多个常量
2.联合的优点
与结构体相比,联合体占用更少的内存空间。
三.枚举、联合使用实例
1.枚举变量注意事项
enum Day{Monday=1,Tuesday,Wednesday,};enum Day kite = Monday;
只能拿枚举常量给枚举变量赋值,才不会出现类型差异。
如以上给kite赋值是合法的,
如果直接写kite = 1则非法。
2.联合实现判断大小端
运用联合体,我们可以编写以下程序判断编译器的存储模式
#define _CRT_SECURE_NO_WARNINGS 1#includeint check_cls(){union Un{char c;int i;}u;u.i = 1;//给i赋值1,此时c也被改变return u.c;//若为小端,c为01//若为大端,c为00}int main(){if (check_cls() == 1){printf("小端\n");}else{printf("大端\n");}}
3.联合大小的计算
上文已经提到,联合体的大小至少是最大成员的大小。
那么这个最大成员的大小是多少呢?
我们看以下程序:
union Un{char arr[5];//5int i;//4}u;int main(){printf("%d", sizeof(u));}
乍一看,五个字节完全够用了,
可u的实际大小却是8个字节。
怎么会这样 QAQ
这让我想起了联合体的好兄弟结构体,
他的好兄弟哟,
满脑子都是内存对齐,
这联合体,也是如此。
我们看他的成员,一个char类型的数组,对齐数要看其元素类型char,对齐数是1;一个是int类型的整型变量,对齐数是4,因此最大对齐数是4。
为了放的下,最终大小对齐到8.
Tips:
联合也存在内存对齐。
来做道题检验一下学会了没有!!!
下面代码的结果是:( )#include union Un{short s[7];int n;};int main(){ printf("%d\n", sizeof(union Un)); return 0;}//选项:A .14B .4C .16D .18
答案是C哦!
题解:联合体向int对齐,7个short一共是14字节,对齐后是16字节。n是单独的4字节,由于是联合体,n与s共用空间,只取最长的元素,故占用16字节。
四.几道经典例题
1.枚举
下面代码的结果是:( )
enum ENUM_A{X1,Y1,Z1 = 255,A1,B1,};enum ENUM_A enumA = Y1;enum ENUM_A enumB = B1;printf("%d %d\n", enumA, enumB);//选项:A .1, 4B .1, 257C .2, 257D .2, 5
本题答案为B,
注意到Z1赋值为255,
X1,Y1,Z1,A1,B1依次为0,1,255,256,257
2.联合
下面程序的输出是:()
#includeint main(){ union { short k; char i[2]; }*s, a; s = &a; s->i[0] = 0x39; s->i[1] = 0x38; printf(“%x\n”,a.k); return 0;}//选项:A .3839B .3938C .380039D .不确定
答案是A哦
题解:如图,位顺序类似小端,低地址在低处,所以39是低地址,在低位,38在高位,所以是3839,故选A。
总结
今天对枚举和联合进行了初步的讲解就结束啦!
希望小伙伴们喜欢!!!OvO