📚 第21讲:自定义类型:联合和枚举 🧩
从“共享内存”到“精准枚举”,解锁C语言的高级数据组织技巧!
联合体省空间,枚举提可读,程序员的“效率双子星”!
📂 目录
- 联合体类型的声明 —— 共享内存的“变形金刚” 🔁
- 联合体的特点 —— 一屋多人住,谁住谁说了算 🏠
- 联合体大小的计算 —— 按最大房间算租金 💰
- 枚举类型的声明 —— 有限选项的“菜单列表” 📋
- 枚举类型的优点 —— 比#define更聪明的常量 🧠
- 枚举类型的使用 —— 让代码“说人话” 💬
📖 正文开始
前面我们学了结构体——把多个数据“打包”成一个整体。
今天,我们学习两个更高级的自定义类型:
- 联合体(union):多个成员共享同一块内存,节省空间!
- 枚举(enum):把有限的取值一一列出,提升可读性!
它们就像C语言的“特种兵”,各有所长!
联合体类型的声明 —— 共享内存的“变形金刚” 🔁
🌟 生活比喻:变形金刚的“形态切换”
想象一个变形金刚:
- 可以是汽车形态
- 也可以是机器人形态
但不能同时是两者!
联合体就像变形金刚:
- 多个成员(形态)
- 共享同一块内存(身体)
- 任一时刻只能“激活”一个成员!
✅ 基本语法
union 联合名 {
成员列表;
};
✅ 示例:int 和 char 共享内存
#include <stdio.h>
union Un {
char c; // 1字节
int i; // 4字节
};
int main() {
union Un un = {0};
printf("联合体大小: %d\n", sizeof(un)); // 输出:4
return 0;
}
🔍 为什么是
4?
因为联合体只为最大的成员分配空间!
int需要4字节,所以整个联合体就是4字节。
联合体的特点 —— 一屋多人住,谁住谁说了算 🏠
🔍 核心特点:所有成员共用同一块内存
✅ 代码1:地址验证
union Un un;
printf("%p\n", &un.i); // 001AF85C
printf("%p\n", &un.c); // 001AF85C
printf("%p\n", &un); // 001AF85C
✅ 三个地址完全相同!
说明i和c是“同居一室”!
✅ 代码2:数据覆盖实验
un.i = 0x11223344; // i = 0x11223344
un.c = 0x55; // c = 0x55 → 覆盖了 i 的最后一个字节
printf("%x\n", un.i); // 输出:11223355
🔍 内存变化图解:
初始:i = 11 22 33 44 ← 小端存储:低地址在右
c → 44
执行 un.c = 0x55 后:
i = 11 22 33 55
c → 55
✅
c修改了i的最低字节!这就是“共享内存”的威力!
联合体大小的计算 —— 按最大房间算租金 💰
🔹 计算规则
- 联合体大小 ≥ 最大成员的大小
- 如果最大成员大小不是最大对齐数的整数倍,要对齐到其整数倍。
✅ 经典练习
union Un1 {
char c[5]; // 5字节,对齐数=1
int i; // 4字节,对齐数=4 → 最大对齐数=4
}; // 大小 ≥5,且是4的倍数 → 实际:8字节
union Un2 {
short c[7]; // 14字节,对齐数=2
int i; // 4字节,对齐数=4 → 最大对齐数=4
}; // 大小 ≥14,且是4的倍数 → 实际:16字节
printf("%d\n", sizeof(union Un1)); // 8
printf("%d\n", sizeof(union Un2)); // 16
联合体的实战应用 💡
🌟 应用1:判断大小端
int check_sys() {
union {
int i;
char c;
} un;
un.i = 1; // i = 00000001 00000000 00000000 00000001
return un.c; // 小端:低字节在低地址 → c=1;大端:c=0
}
✅ 返回
1→ 小端;返回0→ 大端
🌟 应用2:节省内存的礼品清单
❌ 原始设计:浪费空间
struct gift_list {
int stock_number;
double price;
int item_type;
// 所有商品属性全塞进来...
char title[20]; // 图书用
char design[30]; // 杯子/衬衫用
int colors; // 衬衫用
// ... 其他属性
};
❌ 无论什么商品,都占用所有空间!
✅ 优化设计:联合体登场
struct gift_list {
int stock_number;
double price;
int item_type;
union {
struct { char title[20]; char author[20]; int num_pages; } book;
struct { char design[30]; } mug;
struct { char design[30]; int colors; int sizes; } shirt;
} item;
};
✅ 只有当前商品类型的属性占用内存,其他不占用!
空间节省高达 50%~70%!
枚举类型的声明 —— 有限选项的“菜单列表” 📋
🌟 生活比喻:餐厅点餐菜单
餐厅不会让你“随便写菜名”,而是给你一个菜单:
- 红烧肉
- 宫保鸡丁
- 鱼香肉丝
枚举就是编程中的“菜单”——把可能的取值一一列出!
✅ 基本语法
enum 枚举名 {
枚举常量1,
枚举常量2,
...
};
✅ 示例:一周七天
enum Day {
Mon, // 0
Tues, // 1
Wed, // 2
Thur, // 3
Fri, // 4
Sat, // 5
Sun // 6
};
✅ 默认从
0开始,依次递增1。
✅ 自定义值
enum Color {
RED = 2,
GREEN = 4,
BLUE = 8
};
✅ 可以手动指定每个常量的值!
枚举类型的优点 —— 比#define更聪明的常量 🧠
| 优点 | 说明 |
|---|---|
| 可读性强 | FEMALE 比 1 更易理解 |
| 类型安全 | 编译器会检查类型,enum Sex 只能赋 MALE/FEMALE/SECRET |
| 便于调试 | 调试器能显示 MALE,而不是 0 |
| 作用域清晰 | 可以定义在函数内,不会污染全局 |
| 一次定义多个 | 一行代码定义一组相关常量 |
✅ 对比 #define
// 用 #define
#define MALE 0
#define FEMALE 1
#define SECRET 2
// 用 enum
enum Sex { MALE, FEMALE, SECRET };
✅
enum更安全、更清晰、更专业!
枚举类型的使用 —— 让代码“说人话” 💬
enum Color { RED = 1, GREEN = 2, BLUE = 4 };
enum Color clr = GREEN; // ✅ 正确
✅
clr = GREEN;比clr = 2;可读性高100倍!
⚠️ C语言 vs C++
- C语言:可以
clr = 5;(允许整数赋值) - C++:
clr = 5;会报错!类型检查更严格。
✅ 建议:即使C语言允许,也不要用整数直接赋值,保持代码清晰!
🎯 总结:联合与枚举“双剑合璧”
| 类型 | 核心用途 | 关键特点 |
|---|---|---|
| 联合体 | 节省内存、数据转换 | 成员共享内存,任一时刻只一个有效 |
| 枚举 | 提升可读性、类型安全 | 有限取值一一列举,比#define更优 |
🎯 恭喜你!
你已经掌握了C语言中“空间优化”和“代码美化”的两大利器!

2613

被折叠的 条评论
为什么被折叠?



