sizeof(union) 等於最大成員大小 (對齊後)。&union_var == &union_var.member1 == &union_var.member2。union U u = { .member = value };)memcpy)雖然標準限制嚴格,但在實際系統程式 (驅動程式、網路協定解析、序列化) 中常見以下模式:
union {
char bytes[8];
double value;
} converter;
converter.value = 3.1415926535;
for (int i = 0; i < 8; i++) {
printf("Byte %d: 0x%02X\n", i, (unsigned char)converter.bytes[i]);
}
// 輸出 IEEE 754 雙精度浮點數的位元模式
union Packet {
struct {
uint16_t magic;
uint16_t version;
uint32_t payload_len;
uint8_t payload[0]; // 柔性陣列成員 (C99)
} fields;
uint8_t raw[1024]; // 原始位元組緩衝區
};
void parse_packet(const uint8_t *data, size_t len) {
union Packet pkt;
memcpy(&pkt, data, len); // 安全複製
printf("Magic: 0x%04X, Ver: %d, Len: %u\n",
ntohs(pkt.fields.magic),
ntohs(pkt.fields.version),
ntohl(pkt.fields.payload_len));
}
union Example {
char c; // 1 byte
short s; // 2 bytes, align 2
int i; // 4 bytes, align 4
double d; // 8 bytes, align 8
};
// sizeof(Example) == 8 (最大成員 double 對齊至 8)
// 位址偏移:c=0, s=0, i=0, d=0 (全從 0 開始)
struct Message {
uint32_t type;
union {
struct { int x, y; } mouse;
struct { int key; } keyboard;
struct { float x, y, z; } sensor;
}; // 無標籤,成員直接提升到 struct 範疇
};
// 使用
struct Message msg;
msg.type = MSG_MOUSE;
msg.mouse.x = 100; // 直接存取,無需 .union_tag
| 適用場景 | 不適用場景 |
|---|---|
| 硬體暖存器映射、協定封包解析 | 需要同時保存多種類型值 |
| 節省記憶體的互斥欄位 (如符號表) | 跨執行緒共享且無同步機制 |
| 型別安全的位元操作替代方案 | 依賴特定記憶體佈局的可移植程式 |