第21讲:自定义类型:联合和枚举
📚 第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)); // 输出:4return 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 55c → 55
✅
c
修改了i
的最低字节!这就是“共享内存”的威力!
联合体大小的计算 —— 按最大房间算租金 💰
🔹 计算规则
- 联合体大小 ≥ 最大成员的大小
- 如果最大成员大小不是最大对齐数的整数倍,要对齐到其整数倍。
✅ 经典练习
union Un1 {char c[5]; // 5字节,对齐数=1int i; // 4字节,对齐数=4 → 最大对齐数=4
}; // 大小 ≥5,且是4的倍数 → 实际:8字节union Un2 {short c[7]; // 14字节,对齐数=2int 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 00000001return 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, // 0Tues, // 1Wed, // 2Thur, // 3Fri, // 4Sat, // 5Sun // 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语言中“空间优化”和“代码美化”的两大利器!