聯合體(union)是一種構造類型,允許在同一塊內存空間中存儲不同類型的數據——但同一時刻只能存儲其中一種。這與結構體(所有成員並存)本質不同:結構體長度 = 成員長度之和(含對齊),聯合體長度 = 最長成員的長度。
union UnionName {
type1 member1;
type2 member2;
// ...
};
union Dept {
int classNo; // 學生:班級號
char office[20]; // 教師:教研室名
};
// 1. 先定義後聲明
union Dept { int classNo; char office[20]; };
union Dept a, b;
// 2. 定義同時聲明
union Dept { int classNo; char office[20]; } a, b;
// 3. 匿名聯合體直接聲明
union { int classNo; char office[20]; } a, b;
變量.成員 或 指針->成員 訪問單一成員。#include <stdio.h>
#include <string.h>
int main() {
struct Person {
char name[20];
int age;
char job; // 's' 學生, 't' 教師
union {
int classNo;
char office[20];
} dept;
} people[2];
for (int i = 0; i < 2; ++i) {
printf("輸入姓名 年齡 身份(s/t):");
scanf("%s %d %c", people[i].name, &people[i].age, &people[i].job);
if (people[i].job == 's') {
printf("輸入班級號:");
scanf("%d", &people[i].dept.classNo); // 數組名/字符串不需 &,但這裡是 int
} else {
printf("輸入教研室:");
scanf("%s", people[i].dept.office); // office 是數組,自動退化為指針
}
}
printf("\n姓名\t年齡\t身份\t班級/教研室\n");
for (int i = 0; i < 2; ++i) {
if (people[i].job == 's') {
printf("%s\t%d\t%c\t%d\n", people[i].name, people[i].age, people[i].job, people[i].dept.classNo);
} else {
printf("%s\t%d\t%c\t%s\n", people[i].name, people[i].age, people[i].job, people[i].dept.office);
}
}
return 0;
}
union Dept { int classNo; char office[20]; }; // 假設 int 4 字節,office 20 字節
變量 a 內存佈局(共 20 字節):
+--------------------+--------------------+--------------------+--------------------+
| office[0] | office[1] | ... | office[19] | <-- 20 字節
+--------------------+--------------------+--------------------+--------------------+
| classNo (4 bytes) | (padding 16 bytes) | | | <-- 同一地址起始
+--------------------+--------------------+--------------------+--------------------+
賦值 a.classNo = 101 時:前 4 字節寫入 0x00000065,後 16 字節保持不變(殘留數據)。
賦值 strcpy(a.office, "CS Dept") 時:前 8 字節寫入字符串,覆蓋 classNo 位模式。
| 特性 | 結構體 struct | 聯合體 union |
|---|---|---|
| 成員存儲 | 各自獨立內存,同時存在 | 共享同一內存,互斥存在 |
| 總長度 | 成員長度之和(含對齊填充) | 最長成員長度(對齊後) |
| 初始化 | 可整體初始化(C99 指定初始化器) | 標準禁止整體初始化,只能賦值單一成員 |
| 典型用途 | 固定結構的記錄(學生、產品) | 變體記錄、協議數據帧、類型懲罰 |
union Dept *p = &a;,通過 p->classNo 訪問。聯合體是 C 語言實現「變體記錄」與「類型懲罰」的核心機制。理解其共享內存、互斥存儲、長度取最大三大特性,能幫你在嵌入式協議解析、節省內存的異構數據存儲等場景寫出高效、優雅的代碼。