今天我们来聊聊 C 语言里两个特别有意思,但也特别容易让人犯迷糊的自定义类型------联合体(Union)和枚举(Enum)。
如果说上次的结构体(Struct) 是给数据建了一个"独栋别墅",每个成员都有自己的房间(独立的内存空间),那今天这位联合体,就是内存里的"群租房"------大家挤在同一块空间里,你方唱罢我登场。
而枚举 呢?它就像是学校里的"点名册",把一堆相关的常量整整齐齐地列出来,再也不用在代码里写一堆让人头大的 0、1、2 了。
准备好了吗?咱们发车
一、联合体(Union):内存里的"变形金刚"
1. 它到底是个啥?
联合体,顾名思义,就是"联合"在一起。它的声明跟结构体很像,但内核完全不同。

你以为它占了 1 + 4 = 5 个字节?Too young too simple!
实际上,编译器只为最大的那个成员 分配足够的内存空间。因为 int 最大(通常4字节),所以这个联合体只占 4个字节。
这就好比你买了张折叠床,白天是沙发,晚上是床。不管你怎么变,它就占那么大的地儿。
2. 铁证如山:大家的地址都一样!
口说无凭,咱们跑段代码看看:

猜猜输出啥?

没错,仨地址一模一样 !这说明 c 和 i 确实是在同一块内存上"叠罗汉"呢。
3. 牵一发而动全身(大小端实战)
正因为共用内存,你要是改了其中一个,另一个也就跟着变了。来看这个经典的"暗黑魔法":

输出结果是啥?是 11223355。
你会发现,i 的第 4 个字节(也就是最低地址的那个字节)被 c 给"截胡"了,变成了 55。
小魔术 :这其实就是利用了"大小端"的原理。在小端机器上,低位字节存在低地址。咱们改了低地址的
c,自然就改掉了i的最后一个字节。
4. 联合体 vs 结构体:合租 vs 独栋
为了让大家看得更明白,咱们把两者放一起对比:
-
结构体 :各住各屋,互不打扰。
sizeof(struct)会把大家的空间加起来(还要考虑内存对齐)。 -
联合体 :挤在一起,轮流上岗。
sizeof(union)只看最大的那位。
5. 联合体大小计算:别高兴得太早
你以为联合体大小就是"最大成员的大小"?不全对!
它还要遵守内存对齐的规则,跟结构体一样,得对齐到"最大对齐数"的整数倍。
来看两个例子:
联合体1:

最大成员是 c[5],占 5 字节。但最大对齐数是 int 的 4。5 不是 4 的倍数,所以编译器会往上补齐到 8 字节。
联合体2:

short c[7] 占 14 字节。最大对齐数还是 4。14 不是 4 的倍数,补到最近的倍数就是 16 字节。
口诀:联合体大小 = 大于等于最大成员大小,且是最大对齐数的整数倍。
6. 实战:用联合体判断大小端(面试常客!)
既然联合体这么爱"叠罗汉",那我们就可以用它来写个超简洁的大小端判断程序:

原理很简单:i 赋值 1,如果是小端,低地址(也就是 c 的地盘)就是 1;如果是大端,低地址就是 0。一行代码,秀翻全场!
二、枚举(Enum):告别"魔法数字"的点名册
1. 啥时候用枚举?
如果你有一组有限个的常量,比如星期(周一到周日)、颜色(红绿蓝),那就非常适合用枚举。
但如果是"所有的整数"、"地球上的温度"、"全班同学的名字",那千万别用枚举,因为你永远也列不完!
2. 声明与使用

这里的 RED、GREEN、BLUE 就叫枚举常量。
默认情况下,它们从 0 开始依次递增。所以 RED=0,GREEN=1,BLUE=2。
当然,你也可以给它们"走后门"手动赋值:

用的时候就像这样:

3. 实战:模拟交通灯(状态机入门)
枚举最爽的地方在于配合 switch 语句,让代码逻辑像说明书一样清晰。

你看,用 RED、GREEN、YELLOW 写出来的代码,是不是比满屏的 case 0:、case 1: 看着舒服多了?这就是枚举的魅力------自解释性。
三、总结时间到啦!!!
好啦,今天关于联合体(共用体)和枚举的闲聊就到这里。咱们最后划一下重点:
| 类型 | 外号 | 核心特点 | 使用场景 |
|---|---|---|---|
| **联合体 (Union)** | 内存群租房 | 成员共用内存,大小看最大成员,需对齐 | 节省内存、判断大小端、解析数据包 |
| **枚举 (Enum)** | 常量点名册 | 常量从0递增,可读性强 | 状态机(交通灯)、选项配置、代替宏定义 |
一句话记忆:
-
想省钱(省内存)又不怕成员打架?用联合体。
-
想让代码像诗一样好懂?用枚举。
C语言的水很深,但每弄懂一个知识点,我们离大佬的距离就又近了一步。