第21讲:自定义类型:联合和枚举

📚 第21讲:自定义类型:联合和枚举 🧩

从“共享内存”到“精准枚举”,解锁C语言的高级数据组织技巧!
联合体省空间,枚举提可读,程序员的“效率双子星”!


📂 目录

  1. 联合体类型的声明 —— 共享内存的“变形金刚” 🔁
  2. 联合体的特点 —— 一屋多人住,谁住谁说了算 🏠
  3. 联合体大小的计算 —— 按最大房间算租金 💰
  4. 枚举类型的声明 —— 有限选项的“菜单列表” 📋
  5. 枚举类型的优点 —— 比#define更聪明的常量 🧠
  6. 枚举类型的使用 —— 让代码“说人话” 💬

📖 正文开始

前面我们学了结构体——把多个数据“打包”成一个整体。
今天,我们学习两个更高级的自定义类型:

  • 联合体(union):多个成员共享同一块内存,节省空间!
  • 枚举(enum):把有限的取值一一列出,提升可读性!

它们就像C语言的“特种兵”,各有所长!


联合体类型的声明 —— 共享内存的“变形金刚” 🔁

🌟 生活比喻:变形金刚的“形态切换”

想象一个变形金刚:

  • 可以是汽车形态
  • 也可以是机器人形态
    不能同时是两者

联合体就像变形金刚:

  • 多个成员(形态)
  • 共享同一块内存(身体)
  • 任一时刻只能“激活”一个成员!

✅ 基本语法

union 联合名 {
    成员列表;
};
✅ 示例:intchar 共享内存
#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

✅ 三个地址完全相同
说明 ic 是“同居一室”!


✅ 代码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 的最低字节!这就是“共享内存”的威力!


联合体大小的计算 —— 按最大房间算租金 💰

🔹 计算规则

  1. 联合体大小 ≥ 最大成员的大小
  2. 如果最大成员大小不是最大对齐数的整数倍,要对齐到其整数倍。

✅ 经典练习

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更聪明的常量 🧠

优点说明
可读性强FEMALE1 更易理解
类型安全编译器会检查类型,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语言中“空间优化”和“代码美化”的两大利器!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值