struct A {
unsigned short a; // 2 bytes, offset 0
unsigned int b; // 4 bytes, offset 4 (填充 2 bytes)
unsigned char c; // 1 byte, offset 8
}; // 最大成員 4 bytes,總大小對齊到 12 bytes
sizeof(struct A) == 12(非 7)。成員 c 實際佔用 4 bytes 空間(含 3 bytes 填充)。
struct B { char c; int i; short s; }; // 1 + 3填充 + 4 + 2 + 2填充 = 12
struct C { int i; short s; char c; }; // 4 + 2 + 1 + 1填充 = 8 (更緊湊)
優化技巧: 成員按大小遞減排列(大→小)可最小化填充。
offsetof#include <stddef.h> // 標準庫已提供 // 手動實現原理: #define offsetof(TYPE, MEMBER) ((size_t) &(((TYPE*)0)->MEMBER)) // 解析:(TYPE*)0 → 首址為 0 的結構體指標 // ->MEMBER → 取該成員(位址即偏移量) // & → 取位址 → size_t 強轉
struct A { int a; short b; char c; };
// 1. 指定成員初始化 (C99 designated initializers)
struct A a1 = { .a = 1, .b = 2, .c = 3 };
// 2. 順序初始化
struct A a2 = { 1, 2, 3 };
// 3. 逐個賦值
struct A a3; a3.a = 1; a3.b = 2; a3.c = 3;
struct Flags {
unsigned int f1 : 1;
unsigned int f2 : 3;
unsigned int : 0; // 強制下一位元域對齊到下一個 int
unsigned int f3 : 4;
};
:0 強制對齊邊界,跨平台行為一致性較好。
#pragma pack(push, 1) // 1 字節對齊(無填充)
struct Packed { char c; int i; }; // sizeof = 5
#pragma pack(pop)
// 注意:可能導致非對齊存取效能下降或硬體異常(某些架構)
#pragma pack(1) + 手動處理字節序,或定義序列化/反序列化函式避免對齊差異。alignas (C11) 顯式對齊關鍵熱點資料到快取行(64 bytes)。printf("offset %s = %zu\n", #m, offsetof(T, m)) 列印所有成員偏移驗證預期。