当前位置: 首页 > news >正文

C语言自定义类型:联合体与枚举

✅《C语言自定义类型:联合体与枚举》

本文基于 C 语言联合体(union)与枚举(enum)两个核心的自定义类型,通过图示、实例、底层解释进行系统讲解,适合初学者、进阶者与实战开发者阅读。


📚 目录

  • 一、联合体(Union)

    • 1.1 联合体的声明
    • 1.2 联合体的底层特点(核心)
    • 1.3 联合体覆盖示意图(关键)
    • 1.4 结构体 vs 联合体:内存对比图
    • 1.5 联合体大小计算规则(含对齐示意图)
    • 1.6 使用联合体节省空间(实战例子)
    • 1.7 练习:判断大小端
  • 二、枚举类型(Enum)

    • 2.1 枚举声明与默认值规则
    • 2.2 枚举的优点(强烈推荐的原因)
    • 2.3 枚举的底层值映射图
    • 2.4 枚举变量的使用与注意事项
  • 三、联合体 + 枚举:工程开发中的组合模式

  • 四、强化练习(附答案)

  • 五、总结


一、联合体(union)

联合体(Union)与结构体类似,也由多个不同类型的成员组成,但有本质区别:

❗联合体的所有成员共享同一块内存,因此只能同时保存其中一个成员的值。


1.1 联合体的声明

union Un {char c;int i;
};

定义变量:

union Un un;

大小:

printf("%d\n", sizeof(un));

输出通常为 4,因为最大成员 int 占 4 字节。


1.2 联合体的底层特点(核心)

联合体的三个核心点:

✅ 所有成员从地址上完全重叠
✅ 大小至少等于最大成员
✅ 对一个成员赋值会影响其他成员

验证地址:

printf("%p\n", &(un.c));
printf("%p\n", &(un.i));
printf("%p\n", &un);

三个地址一致,这说明:

c 和 i 完全重叠,共用同一块内存。


1.3 联合体覆盖示意图(关键)

下面是联合体写入两个成员时的行为示意图:

假设:

union Un {char c;  // 1 字节int  i;  // 4 字节
};

写入 int:

un.i = 0x11223344;内存(小端机示意):
┌──┬──┬──┬──┐
│44│33│22│11│
└──┴──┴──┴──┘↑c(i)也使用这些字节

再写入 char:

un.c = 0xAA;

结果:

┌──┬──┬──┬──┐
│AA│33│22│11│
└──┴──┴──┴──┘

这个覆盖说明:

写入最小的成员会覆盖最大成员的低地址部分。


1.4 结构体 vs 联合体:内存对比图

结构体(struct)内存布局:

struct S {char c;     //1 字节int  i;     //4 字节(对齐到4)
};内存:
┌────┬──────┬───────────┐
│ c  │ pad   │   i(4字节) │
└────┴──────┴───────────┘

联合体(union)内存布局:

union U {char c;     //1 字节int  i;     //4 字节
};内存:
┌────────────┐
│ 共享的 4 字节 │
└────────────┘

总结:

类型各成员是否独立占用空间大小
struct✅ 是累加 + 对齐
union❌ 否(共享)最大成员大小

1.5 联合体大小计算规则(含对齐示意图)

规则:

  1. 大小 >= 最大成员大小
  2. 大小必须对齐到最大对齐数的整数倍

例 1:

union U1 {char c[5];  //5 字节int  i;     //4 字节
};

最大成员 = c[5]
最大对齐 = int 的 4 字节

所以 U1 大小对齐到 8:

sizeof(U1) = 8

示意图:

c[5] ----> 5 字节
对齐到 4 字节倍数 → 8

1.6 使用联合体节省空间(实战例子)

文档例子使用“礼品兑换单”解释联合体节省空间的作用。

不使用联合体(浪费空间)

struct gift {int stock;double price;int type;char title[20];char author[20];int  pages;char design[30];int colors;int sizes;
};

无论是哪种商品,都包含所有字段,非常浪费。


使用联合体(节省空间 ✅)

struct gift {int stock;double price;int type;union {struct { char title[20]; char author[20]; int pages; } book;struct { char design[30]; } mug;struct { char design[30]; int colors; int sizes; } shirt;} item;
};

图示:

┌─────────────┐
│ 公共属性      │
├─────────────┤
│   union(共享) │← 根据类型使用不同数据
└─────────────┘

1.7 练习:判断大小端

int check_sys() {union {int i;char c;} un;un.i = 1;return un.c; //1小端 0大端
}

利用联合体共享内存的特性,巧妙判断字节序。


二、枚举类型(enum)

枚举用于将一组离散、有限的值定义为常量。


2.1 枚举声明与默认值规则

示例:

enum Day {Mon,Tues,Wed,Thur,Fri,Sat,Sun
};

默认从 0 递增

Mon=0, Tues=1, … Sun=6

也可以手动赋值:

enum Color {RED = 2,GREEN = 4,BLUE = 8
};

2.2 使用枚举的优点(强烈推荐的原因)

特性#defineenum
是否有类型检查❌ 无✅ 有
可读性一般✅ 高
调试时是否有符号❌ 无✅ 有
可否局部定义❌ 否✅ 是

总结:

✅ 枚举比 #define 更安全、更清晰、更专业。


2.3 枚举的底层值映射图

enum Color { RED=1, GREEN=2, BLUE=4 };对应映射关系:RED   →  1
GREEN →  2
BLUE  →  4

本质上:

枚举常量是整数常量(int 类型)。


2.4 枚举变量的使用与注意事项

enum Color clr = GREEN;

C 允许这样:

clr = 100;  //合法

但 C++ 不允许(更严格的类型检查)。


三、联合体 + 枚举:工程开发中的组合模式

在实际工程(网络协议、变长数据结构、事件系统)中常出现:

✅ 用枚举表示类型
✅ 用联合体存储不同类型的数据

示例:

enum Type { BOOK, MUG, SHIRT };struct Gift {int stock;double price;enum Type t;union {struct { char title[20]; char author[20]; int pages; } book;struct { char design[30]; } mug;struct { char design[30]; int colors; int sizes; } shirt;} item;
};

这是 C 风格多态的经典写法。


四、强化练习(附答案)

✅ 练习 1

下面联合体大小是多少?

union U {char c[3];double d;
};

最大成员是 double = 8
对齐 8
所以:

sizeof(U) = 8


✅ 练习 2

以下枚举值是多少?

enum A {X=3, Y, Z=10, W};

序号:

X=3
Y=4
Z=10
W=11


✅ 练习 3

判断输出:

union U {int i;char c;
};union U u;
u.i = 0x88776655;
printf("%x\n", u.c);

在小端机上结果:

55


五、总结

本文系统介绍了:

✅ 联合体(union)

  • 所有成员共享内存
  • 大小由最大成员和对齐决定
  • 可用于节省空间
  • 可用于大小端判断
  • 常与枚举一起用于表达多种数据类型

✅ 枚举(enum)

  • 可读性提升
  • 具备类型检查
  • 可调试性强
  • 常用于状态、类别表示

结构体、联合体、枚举构成了 C 语言自定义类型的全部核心内容,是写出高质量 C 程序的基础。

http://www.dtcms.com/a/593060.html

相关文章:

  • 在线网站推广工具WordPress 付费下载阅读
  • Windows2008 如何禁用FSO?
  • 了解一下LSTM:长短期记忆网络(改进的RNN)
  • 【微服务 - easy视频 | day03】服务与服务之间的调用
  • 网站建设定做mvc网站建设的实验报告
  • CMP(类Cloudera CMP 7 404版华为Kunpeng)告别CDH/CDP,拥抱自主可控的新时代
  • 生成ios钱包pkpass文件
  • Paimon——官网阅读:理解文件
  • 做网站应该学什么语言网站建设裕鸿国际
  • Xenium数据分析 | 使用Xenium Ranger重新分析数据
  • MySQL 8.0 新特性详解:窗口函数,开启数据分析的潘多拉魔盒
  • 基于模板匹配的数字和大写字母识别(Matlab)
  • 网站编程赚钱企业门户网站 php
  • 网站有什么到期网站空间哪里买
  • LeetCode 分类刷题:2816. 翻倍以链表形式表示的数字
  • 一文掌握,soular安装与配置
  • Whole-Body Control——双足机器人全身控制技术 论文阅读笔记
  • LeetCode hot100:240 搜索二维矩阵 II:三种解法对比
  • Wireshark笔记-DNS流程与数据包解析
  • SRv6论文阅读
  • 做电子烟外贸网站有哪些建设银行亚洲官方网站
  • 11.9 LeetCode 题目汇总与解题思路
  • leetcode 707 设计链表
  • dedecms_v5.6室内装饰设计公司企业网站模板.rar免费的素材网站有哪些
  • S7.Net documentation 文档中文说明书
  • 深度学习入门:从理论到实践
  • ts-静态类型检查,自动编译,ts类型 01
  • 文本插值,属性绑定,条件渲染,列表渲染
  • .NET周刊【11月第1期 2025-11-02】
  • C# 垃圾回收机制深度解析