union 關鍵字用法與 struct 相似,但所有成員共用同一塊內存空間,同一時刻只能存儲一個成員的值。空間大小等於最大成員的大小,所有成員起始地址相同(偏移量為 0)。
union StateMachine {
char character;
int number;
char *str;
double exp;
};
上例中 double 佔 8 字節,故 StateMachine 大小為 8 字節。主要用途:節省空間,適用於「數據互斥、不同時存在」的場景。
經典面試題:
union { int i; char a[2]; } *p, u;
p = &u;
p->a[0] = 0x39;
p->a[1] = 0x38;
// 問:p->i 的值為多少?
高字節存低地址,低字節存高地址。a[0] 是高字節,a[1] 是低字節。
結果:0x39380000(假設 int 32 位,高 16 位補 0)。
低字節存低地址,高字節存高地址。a[0] 是低字節,a[1] 是高字節。
結果:0x00003839。
利用 union 成員共用地址特性,將 int 置 1,檢查最低地址字節:
int checkSystem() {
union {
int i;
char ch;
} c;
c.i = 1;
return (c.ch == 1); // 1 = 小端, 0 = 大端
}
x86 架構為小端模式,內存中低地址存儲低字節(0x01)。
#include
int main() {
int a[5] = {1,2,3,4,5};
int *ptr1 = (int *)(&a + 1);
int *ptr2 = (int *)((int)a + 1);
printf("%x,%x", ptr1[-1], *ptr2);
return 0;
}
&a + 1:指針類型為 int (*)[5],+1 跳過整個數組(20 字節),ptr1[-1] 即 a[4] = 5。(int)a + 1:將地址轉為整數後 +1,僅偏移 1 字節。小端模式下,*ptr2 讀取的 4 字節為 00 00 00 02,即 0x02000000。輸出:5,2000000(十六進制)。