自定义类型:数组,结构体,联合体,枚举。前面一些我们已经讲过了,接下来我们讲联合体和枚举。
一.联合体
1.联合体类型的声明
像结构体一样,联合体也是由一个或者多个成员构成,这些成员可以不同的类型。
但是编译器只为最大的成员分配足够的内存空间。联合体的特点是所有成员共用同一块内存空间。所以联合体也叫:共用体。记住:我们给联合体其中一个成员赋值,其他成员的值也跟着变化。
我们举例结构体和联合体设置相同的成员比较来看它们所内存的大小。
结构体我们按之前的分析可以得到,但是这个联合体怎么就是4个字节了呢?这个时候我们再来看第二条规则:联合体的特点是所有成员共用同一块内存空间,它们是怎么同时公用一块空间得呢?我们来探讨联合体的特点。
2.联合体的特点
联合的成员是共用同一块内存空间的,这样一个联合变量的大小,至少是最大成员的大小(因为联合至少得有能力保存最大的那个成员)
从上面打印的地址我们知道了c和i存放的时候重叠了,打印出一样的地址,c和i共用一块空间。
这就是联合体的特点。但是有一个问题,c和i占用同一块空间,当我们改c的时候i不会改变吗?我们给它们赋值并调试看一下。
确实如此,当我们改i的时候就把c改了,改c的时候就把i改了。那我们那它有什么用呢?其实我们用的就是联合体的特点,用在它们的成员不能同时使用的时候,我们只是找适合的场景来用它,而不是强行来用它。
我们来看一下相同成员的结构体和联合体对比,我们再对比一下相同成员的结构体和联合体的内存布局情况。
3.联合体大小的计算
联合的大小至少是最大成员的大小。当最大成员不是最大对齐数的整数倍的时候,就要对齐到最大对齐数的整数倍。
来看例子:
所以千万不要认为联合体的大小就是最大成员的大小,第二个规则:当最大成员不是最大对齐数的整数倍的时候,就要对齐到最大对齐数的整数倍。
再练习一个
最大对齐数为4,而最大成员的大小为14,不是4的整数倍,要对齐到4的整数倍上去,所以打印结果为16。
使用联合体是可以节省空间的,举例:
比如,我们要搞一个活动,要上线一个礼品兑换单,礼品兑换单中有三种商品:图书、杯子、衬衫。
每一种商品都有:库存量、价格、商品类型和商品类型相关的其他信息。
图书:书名、作者、页数
杯子:设计
衬衫:设计、可选颜色、可选尺寸。
我们提取总结来看三个商品里有什么:
我们来直接写出一下结构:
上述的结构其实设计的很简单,用起来也方便,但是结构的设计中包含了所有礼品的各种属性,这样使得结构体的大小就会偏大,比较浪费内存。因为对于礼品兑换单中的商品来说,只有部分属性信息是常用的。比如:商品是图书,就不需要design、colors、sizes。
所以我们就可以把公共属性单独写出来,剩余属于各种商品本身的属性使用联合体起来,这样就可以介绍所需的内存空间,一定程度上节省了内存。
如果对你有用的话,请给作者留下一个: