文章目录
- 1.联合体
- 1.1联合体的声明
- 1.2联合体的特点
- 1.3联合体的大小计算
- 联合体的使用案例
- 2.枚举
- 2.1枚举类型的声明
- 2.2枚举类型的优点(为什么使用枚举)
- 2.3枚举类型的使用
- 结语
1.联合体
1.1联合体的声明
和结构体一样,联合体也是由一个或多个成员构成,同样,这些成员也可以是不同的类型。
但是,编译器只会为最大的成员分配足够的内存空间。联合体的特点是所有成员共用同一块内存空间。所以,联合体也叫共用体
#include
//联合体的声明 union Un {char c1; int i; char c2; }; int main() {//创建一个union Un类型的临时变量 union Un un = { 0 }; //计算联合体变量的大小 printf("union Un 大小为%zd", sizeof(un)); return 0; } 为什么是4呢?
我们就来了解联合体的特点吧
1.2联合体的特点
联合的成员是共用同一块内存空间,所以一个联合体变量的大小至少是最大成员的大小(因为联合至少得有能力存放最大的成员)。
#include
//联合体的声明 union Un {char c1; int i; }; int main() {//创建一个union Un类型的临时变量 union Un un = { 0 }; //查看联合成员的地址 printf("成员i 的地址为 %p\n", &un.i); printf("成员c1的地址为 %p\n", &un.c1); printf("联合体un的地址为%p\n", &un.c1); return 0; } 可以看到输出的三个地址一模一样。
#include
//联合体的声明 union Un {char c1; int i; }; int main() {//创建一个union Un类型的临时变量 union Un un = { 0 }; un.i = 0x11223344; un.c1 = 0x55; //查看联合体成员的值(16进制) printf("成员i的为%x\n", un.i); return 0; } 我们通过调试可以看到,i的第4个字节的内容被修改为了55。
这又证明了,联合体的所有成员是共用同一块空间。
成员相同的结构体和联合体进行比较
#include
struct Str {char c1; int i1; }; union Un {char c2; int i2; }; int main() {printf("struct Str的大小为%zd\n", sizeof(struct Str)); printf("union Un的大小为%3zd", sizeof(union Un)); return 0; } 他们的成员大小相同,成员顺序相同,但输出的结果还是不同,也就是说结构体和联合体对待成员的存放是不同的。
结构体每个成员有独立的空间,而联合体是共用一块空间
1.3联合体的大小计算
1.联合体的大小至少是最大成员的大小
2.如果最大成员的大小不是最大对齐数的整数倍时,空间大小要对齐到最大对齐数的整数倍
看代码:
union Un1//最大对齐数为4(int) {char ch[5];//大小为5(最大) int i;//大小为4 }; union Un2//最大对齐数为4(int) {short sh[5];//大小为10(最大) int i;//大小为4 }; union Un3//最大对齐数为8(long long) {int arr[5];//大小为20(最大) long long lg;//大小为8 }; int main() {printf("union Un1的大小为%zd\n", sizeof(union Un1)); printf("union Un2的大小为%zd\n", sizeof(union Un2)); printf("union Un3的大小为%zd\n", sizeof(union Un3)); return 0; }
联合体的使用案例
联合体的使用案例
假如我们要搞⼀个活动,要上线⼀个礼品兑换单
礼品兑换单中有三种商品:图书、杯⼦、衬衫。
每种商品都有:库存,价格,商品类型,我们称之为公共属性
其中每个商品有各自的特殊属性
图书:书名,作者,页数
杯子:设计方案
衬衫:设计方案,颜色,尺寸
解决方法一:
struct gift_list {//公共属性 int stock_number;//库存 double price;//价格 int item_type;//商品类型 //特殊属性 char Title[20];//书名 char Author[20];//作者 int Num_page;//页数 char Design;//设计方案(杯子和衬衫都有设计方案) char Colors[10];//颜色 int Size;//尺寸 };
上面的的代码,很暴力,也很方便,但是结构的设计中包含了所有礼物的属性,这样会使得结构体的大小会偏大,比较浪费空间。而且对于单个商品来说,只有部分属性是我要用的。
比如商品是衬衫的话我要用的就是Design、Colors、Size,而Title、Author、Num_page就是不需要的属性
所有我们可以把公共属性独立写出来,剩余各种商品本身的特殊属性就可以使用联合体。这样就可以在一定程度上节省空间。
struct Gift_List {//公共属性 int stock_number;//库存 double price;//价格 int item_type;//商品类型 union MyUnion {struct {char Title[20];//书名 char Author[20];//作者 int Num_page;//页数 }book; struct {char Design;//设计方案(杯子和衬衫都有设计方案) }mug; struct {char Design;//设计方案(杯子和衬衫都有设计方案) char Colors[10];//颜色 int Size;//尺寸 }shirt; }item; };
2.枚举
2.1枚举类型的声明
顾名思义就是将可能的元素进行一一列举
例如我们生活中的:一周的星期一到星期日、十二个月份、三原色;这些都可以一一列举
附上代码
enum Colors// {RED, BLUE, GREEN }; enum Week_By_Day {Mon, Tues, Wed, Thur, Fri, Sat, Sun };
以上定义的 颜色,一周都是枚举类型。
而{}里的内容是枚举类型里的可能取值,这也叫做枚举常量。
这些可能取值都是有值的(创建常量的时候肯定是要赋值的)
枚举常量默认从0开始,依次递增1,当然,在声明枚举类型的时候也可以赋初始值。
enum Direction {NORTH,//初始值在没有赋值的情况下就是0 //后面的值发生改变也不会改变前面的值 EAST, WEST = 5, SOUTH }; int main() {printf("%d\n", NORTH); printf("%d\n", EAST); printf("%d\n", WEST); printf("%d\n", SOUTH); return 0; }
初始值在没有赋值的情况下就是0,后面的值发生改变也不会改变前面的值
2.2枚举类型的优点(为什么使用枚举)
明明我们有#define 来定义常量,为什么要使用枚举?
1.增加代码的可读性和可维护性
2.和#define定义的标识符进行比较,枚举有类型检查,更加严谨
3.便于调试,预处理阶段会直接将#define定义的符号替换为原来的符号
4.使用更方便,一次可以定义多个常量
5.枚举常量是遵循作用域规则的,枚举声明在某个函数内,只能在该函数内部使用
2.3枚举类型的使用
#include
enum Colors {RED,//0 BLUE,//1 GREEN//2 }; int main() {enum Color clr = GREEN;//使⽤枚举常量给枚举变量赋值 printf("clr的值为%d", clr); return 0; } 补充:
那我们是否可以拿整数给枚举变量赋值呢?在C语言中是可以的,但是在C++是不行的,C++的类型检查比较严格。
结语
最后感谢您能阅读完此片文章,如果有任何建议或纠正欢迎在评论区留言。如果您认为这篇文章对您有所收获,点一个小小的赞就是我创作的巨大动力,谢谢