结构体与共用体
🎯 一句话秒杀:结构体是把不同类型的数据打包成一个新类型;共用体是让不同类型共享同一块内存(改一个全变)。
① 📊【历年真题考情】
本章(结构体与共用体)在广东专升本计算机统考中的位置:
| 项目 | 结论 |
|---|---|
| 出题频次 | ⭐⭐⭐——2026 考纲全解标注"结构体与共用体:单选、判断、简答,约5分,⭐⭐⭐;结构的定义与使用 3/4 年(2024 考)" |
| 常考题型 | 单选(2022 单选16、2024 单选11)、判断(2024 判断1、2023 判断8)、简答(struct vs union) |
| 预估分值 | 5~15 分 / 200 分(约 3%~8%) |
| 考纲归属 | 2026 考纲「复合数据」考点8(结构体、共用体、枚举、typedef) |
考场真实出现过的高频题:
- 2022 单选16:结构体变量分配的内存容量 → 各成员所需总和(含对齐)
- 2023 单选:关于结构体错误的说法 → 由系统直接提供(错,是用户自定义)
- 2023 判断8:结构体成员存续期驻留内存 → 对
- 2024 单选11:结构体变量执行期间 → 所有成员一直驻留在内存中(union 才共享)
- 2024 判断1:结构体成员用
.成员名引用 → 对
🎯 学习目标:学完本章,你能 ① 判断 struct 和 union 的内存分配区别;② 说出结构体是"用户自定义类型";③ 正确访问结构体成员(. 和 ->);④ 用 typedef 简化类型书写——这四类题就是本章真题的全部考法。
② 🗣️【零基础大白话引入】
结构体是什么? 想象你要登记学生信息:学号、姓名、成绩——三个不同类型的数据。你可以开三张表分别记,但更聪明的办法是做一个"档案袋",把这三样装在一起——这个"档案袋"就是结构体。
结构体 vs 共用体(关键区别):
- 结构体 struct = 每个人一个专属储物柜(每个成员都有自己独立的格子)
- 共用体 union = 一群人共用一个柜子(放了这个就不能放那个,改一个全变)
为什么用结构体?
- 打包数据:把相关数据组织成一个整体,好管理
- 数组升级:结构体数组 = 一叠档案袋
- 文件配合:fwrite 可以把整个结构体直接写入文件
💡 本章主线:定义(档案袋)→ 访问(. 和 ->)→ 数组/指针 → 共用体(共享柜)→ typedef(起外号)。核心就一个对比:struct 各存各的,union 共用一个。
③ 📖【正式核心知识点讲解】
本章知识点 = 考纲要求 + 历年真题实际考过的内容。
3.1 结构体的定义
struct 结构体名 {
类型 成员1;
类型 成员2;
...
}; // ⚠️ 这里的分号不能少!// 定义学生类型
struct Student {
int id; // 学号
char name[20]; // 姓名
float score; // 成绩
}; // ← 分号!3.2 结构体变量的定义
// 方式1:先定义结构体类型,再定义变量
struct Student stu1, stu2;
// 方式2:定义类型的同时定义变量
struct Student {
int id;
char name[20];
float score;
} stu1, stu2;
// 方式3:直接定义变量(省略结构体名)
struct {
int id;
char name[20];
float score;
} stu1, stu2;初始化
struct Student stu1 = {1001, "张三", 85.5};
struct Student stu2 = {1002, "李四", 92.0};3.3 结构体是用户自定义类型(2023 单选 必考)
结构体是"用户自定义类型"(derived/user-defined type),不是系统直接提供的类型!
C 语言类型分两类:
| 类型 | 例子 | 谁定义 |
|---|---|---|
| 基本类型 | int, char, float, double | 系统提供 |
| 用户自定义类型 | struct, union, enum, typedef | 用户自己定义 |
✅ 2023 单选:关于结构体的错误说法 → B. 由系统直接提供(错——结构体是用户自定义的)
3.4 结构体成员的访问
通过成员运算符 .(2024 判断1 必考)
struct Student stu;
stu.id = 1001; // 赋值
strcpy(stu.name, "张三"); // 字符串成员赋值(不能用=)
stu.score = 85.5;
printf("%d %s %.1f", stu.id, stu.name, stu.score);✅ 2024 判断1:"结构体变量的成员可以通过
.成员名来引用其值" → 对 记忆:结构体变量用.,结构体指针用->
🚨 红牌警告
结构体中的字符数组不能直接用
=赋值!cstu.name = "张三"; // ❌ 错误!字符数组不能这样赋 strcpy(stu.name, "张三"); // ✅ 用strcpy
3.5 结构体与指针
结构体指针
struct Student stu = {1001, "张三", 85.5};
struct Student *p = &stu;
// 以下三种方式等价
stu.score = 90; // 直接访问
(*p).score = 90; // 括号不能省!
p->score = 90; // 用 -> 最常用 ✅🔑 秒杀秘籍
p->成员等价于(*p).成员——箭头指向运算符专门用于结构体指针 括号不能省:*p.score等价于*(p.score)— 但p.score是错的(p是指针不是结构体变量)
3.6 结构体做函数参数
// 值传递(整个结构体拷贝,效率低)
void print_stu(struct Student s) {
printf("%d %s %.1f", s.id, s.name, s.score);
}
// 指针传递(只传地址,效率高 ✅)
void print_stu(struct Student *s) {
printf("%d %s %.1f", s->id, s->name, s->score);
}🚨 红牌警告
结构体做参数时,值传递会拷贝整个结构体! 结构体很大时非常浪费内存和CPU 建议大规模用指针传递,小规模用值传递
3.7 结构体数组
struct Student class[3] = {
{1001, "张三", 85.5},
{1002, "李四", 92.0},
{1003, "王五", 78.0}
};
// 访问
printf("%s", class[0].name); // 张三
class[1].score = 95.0; // 修改3.8 结构体的内存分配(2022 单选16 必考)
结构体变量占用的内存 = 各成员所需空间的总和(含对齐)
struct S { char c; int i; };
// sizeof(S) = 8(char 1 + int 4,对齐后占 8)✅ 2022 单选16:结构体变量分配的内存容量为 → A. 各成员所需总和(含对齐) 解析:B"仅第一成员"、C"最大成员"、D"最后成员"都是错的——只有共用体才取最大成员
✅ 2024 单选11:C 语言结构体类型变量在程序执行期间 → A. 所有成员一直驻留在内存中 解析:结构体定义后所有成员同时分配(含对齐);union 才是成员共享同一块内存

3.9 共用体(联合体)
union Data {
int i;
float f;
char c;
};关键特性:所有成员共享同一块内存(2024 单选11 对比)
union Data d;
d.i = 10; // 内存中存放 10
printf("%d", d.i); // 10 ✅
printf("%f", d.f); // ❌ 乱码(因为d.f和d.i共享同一块内存)| 特点 | struct(结构体) | union(共用体) |
|---|---|---|
| 内存分配 | 各成员独立存储 | 所有成员共享同一块内存 |
| 总大小 | 各成员大小之和(+对齐) | 最大成员的大小 |
| 同时存储 | 所有成员共存 | 只能存一个 |
| 用途 | 组织不同类型的数据 | 节省空间/多选一 |
struct S { char c; int i; }; // sizeof = 8(含对齐)
union U { char c; int i; }; // sizeof = 4(取int的大小)✅ 2024 单选11 对比:union 才是"只有一个成员驻留"——结构体所有成员共存,共用体只能存一个 记忆:struct 各存各的(总和),union 共用一个(最大)
3.10 typedef——给类型起别名
typedef struct Student {
int id;
char name[20];
float score;
} Stu; // Stu 就是 struct Student 的别名
// 现在可以直接写:
Stu stu1; // 等价于 struct Student stu1;
Stu *p; // 结构体指针
Stu class[30]; // 结构体数组不用typedef的对比
// 没有typedef
struct Student stu1; // 每次都要写 struct
// 有typedef
typedef struct { // 甚至可以省略结构体名
int id;
char name[20];
float score;
} Stu;
Stu stu1; // 简洁!3.11 枚举 enum(考纲考点8 · 补充)
枚举:把一组有名字的常量打包成一个类型
enum Weekday { Mon, Tue, Wed, Thu, Fri, Sat, Sun };
// Mon=0, Tue=1, ..., Sun=6(默认从0开始)
enum Weekday today = Wed;
printf("%d", today); // 输出 2| 特性 | 说明 |
|---|---|
| 本质 | 一组命名的整型常量 |
| 默认值 | 从 0 开始递增 |
| 可指定 | enum { A=5, B, C }; → A=5, B=6, C=7 |
| 用途 | 提高代码可读性(星期/颜色/状态) |
💡 枚举与 typedef 都是用户自定义类型,考纲考点8 明确列入,需了解。
④ 🧪【真题同源例题】
例题 1:入门基础题(先热热身)
struct S { char c; int i; };
union U { char c; int i; };
printf("%d %d", sizeof(struct S), sizeof(union U));逐项推演:
struct S:char 1 + int 4,对齐后 → 8union U:取最大成员 int 的大小 → 4- 输出:
8 4
✅ struct=各成员总和(含对齐),union=最大成员——这是全章最核心的对比。
例题 2:2022 真题改编(内存容量)
结构体变量分配的内存容量为( )
A. 各成员所需总和(含对齐) B. 仅第一成员 C. 最大成员 D. 最后成员
逐项分析:
- A:各成员总和(含对齐)——结构体 ✅
- B:仅第一成员 ❌
- C:最大成员——那是 union ❌
- D:最后成员 ❌
✅ 答案 A(2022 单选16 原题)。记忆:struct 总和,union 最大
例题 3:2024 真题改编(成员驻留)
C 语言结构体类型变量在程序执行期间( )
A. 所有成员一直驻留在内存中 B. 只有一个成员驻留在内存中 C. 部分成员驻留 D. 没有成员驻留
逐项分析:
- A:所有成员同时分配、一直驻留 ✅
- B:只有一个驻留——那是 union ❌
- C:部分驻留 ❌
- D:不驻留 ❌
✅ 答案 A(2024 单选11 原题)。注意:B 是 union 的特征,别搞混!
例题 4:2023 真题改编(用户自定义类型)
下列关于结构体的说法,错误的是( )
A. 结构体是用户自定义类型 B. 结构体由系统直接提供 C. 结构体可包含不同类型成员 D. 结构体成员可用 . 访问
逐项分析:
- A:结构体是用户自定义类型 → 对
- B:由系统直接提供 → 错(用户自定义)❌ 选它
- C:可包含不同类型成员 → 对
- D:成员用
.访问 → 对
✅ 答案 B(2023 单选同款)。记忆:struct/union/enum/typedef 全是用户自定义类型
例题 5:成员访问
struct Student stu = {1001, "张三", 85.5};
struct Student *p = &stu;
printf("%.1f", p->score);逐项推演:
p->score:箭头运算符,等价于(*p).score(*p)解引用得到 stustu.score= 85.5- 输出:
85.5
✅ 三种写法
stu.score、(*p).score、p->score完全等价(2024 判断1 关联)
⑤ ⚠️【历年真题高频扣分坑】
| # | 陷阱 | 错误做法 | 正确做法 | 出处 |
|---|---|---|---|---|
| 1 | struct/union 内存混淆 | 以为 union 也是总和 | struct=总和(含对齐);union=最大成员 | 2022 单选16 |
| 2 | 成员驻留误解 | 以为部分成员驻留 | 结构体所有成员同时分配 | 2024 单选11 |
| 3 | 结构体当系统类型 | 以为系统直接提供 | 结构体是用户自定义类型 | 2023 |
| 4 | 字符数组成员赋值 | stu.name = "张三" | 必须 strcpy(stu.name, "张三") | 经典 |
| 5 | *p.成员 括号 | *p.score 当解引用成员 | (*p).score 括号不能省 | 经典 |
| 6 | -> vs . | 指针用 . | 指针用 ->,变量用 . | 2024 判断1 |
| 7 | typedef 后还写 struct | struct Stu stu1; | typedef 后直接 Stu stu1; | 经典 |
| 8 | 大结构体值传参 | 大结构体值传递 | 指针传递更高效 | 经典 |
| 9 | enum 默认值 | 以为从 1 开始 | enum 默认从 0 开始 | 考纲 |
| 10 | 结构体定义忘分号 | struct S {...} 无 ; | 定义结束必须有 ; | 经典 |
📌 最值钱的一条:第 1、2 条(struct=总和 vs union=最大、所有成员驻留)是 2022/2024 单选原题——"struct 各存各的,union 共用一个" 一句口诀拿 6 分。
⑥ 📝【课后自测练习题】
1. 结构体变量分配的内存容量为( )(2022 真题风格)
A. 各成员所需总和(含对齐) B. 仅第一成员 C. 最大成员 D. 最后成员
2. C 语言结构体类型变量在程序执行期间( )(2024 真题风格)
A. 所有成员一直驻留在内存中 B. 只有一个成员驻留 C. 部分成员驻留 D. 没有成员驻留
3. 下列关于结构体的说法,错误的是( )(2023 真题风格)
A. 结构体是用户自定义类型 B. 结构体由系统直接提供 C. 结构体可包含不同类型成员 D. 结构体成员可用 . 访问
4. 已知 struct Student stu; struct Student *p = &stu;,以下写法错误的是( )(2024 真题风格)
A. stu.score B. (*p).score C. p->score D. p.score
5. union U { char c; int i; }; 的 sizeof 是( )(经典)
A. 5 B. 8 C. 4 D. 1
👆 点击展开参考答案与解析
第1题:A. 各成员所需总和(含对齐)
- 结构体=各成员总和;union 才是最大成员(2022 单选16 原题)
第2题:A. 所有成员一直驻留在内存中
- 结构体所有成员同时分配;B"只有一个驻留"是 union 的特征(2024 单选11 原题)
第3题:B. 结构体由系统直接提供
- 结构体是用户自定义类型,不是系统提供的(2023 单选同款)
第4题:D. p.score
- p 是指针,要用
p->score或(*p).score;p.score错误(.用于结构体变量)
第5题:C. 4
- union 取最大成员大小:char 1 vs int 4 → 4
📝 原有闭卷真题挑战(保留原内容 + 扩充至 10 题)
(点击下方空白查看答案)
1. struct 和 union 的内存分配区别?
2. 结构体里面的字符数组成员如何赋值?
3. 写出sizeof结果:
struct { char a; int b; } s;
4. 结构体指针访问成员用哪个运算符?
5. typedef 的作用?(扩充题)
6. 结构体变量分配的内存容量是? A.总和 B.首成员 C.最大成员 D.末成员
7. 结构体执行期间,成员驻留情况? A.全部 B.一个 C.部分 D.没有
8. 结构体是____类型(系统/用户自定义)?
9. union { char c; int i; } 的 sizeof?
10. enum { A, B, C }; 中 B 的值是?👆 点击展开答案
struct各成员独立存储(共存),sizeof=和对齐;union共享内存(只能存一个),sizeof=最大成员
用
strcpy(不能用 = 直接赋值)8(char占1,int占4,对齐后占用8)
->(箭头指向运算符)给已有类型起别名,简化书写
A. 总和(含对齐)
A. 全部驻留(union 才是一个)
用户自定义类型(不是系统提供的)
4(取最大成员 int 的大小)
1(enum 从 0 开始:A=0, B=1, C=2)
📖 教材习题对照
| 教材习题 | 知识点 | 难度 |
|---|---|---|
| 习题9.1~9.3 | 结构体定义与使用 | ⭐⭐ |
| 习题9.4 | 结构体数组 | ⭐⭐ |
| 习题9.8 | 结构体指针 | ⭐⭐⭐ |
| 习题9.9 | 共用体 | ⭐⭐⭐ |
| 习题9.10 | typedef应用 | ⭐⭐ |
对应教材:谭浩强《C程序设计》第5版 → 第9章 用户自己建立数据类型 对应考试大纲:考点9 — 结构体与共用体
📺 配套视频
复习到本考点 → 先看视频补讲,再刷上面「闭卷挑战」。