`sizeof` 是 C/C++ **單目運算子** (非函數),在**編譯期** 計算運算元佔用的儲存大小 (位元組數),結果型別為 `size_t` (無號整數)。掌握其規則對正確配置記憶體、序列化、跨平台開發至關重要。
// 1. 型別運算元:必須加括號
sizeof(int)
sizeof(struct MyStruct)
// 2. 運算式/變數運算元:括號可選
sizeof variable
sizeof (expression)
sizeof arr[10] // 不會評估運算式,僅推導型別
| 運算元類別 | 結果說明 | 典型值 (x86-64 Linux/GCC) |
|---|---|---|
| 基本型別 | 該型別物件大小 | char=1, short=2, int=4, long=8, float=4, double=8, long double=16 |
| 指標型別 | 指標本身大小 (位址寬度) | 32位=4, 64位=8 (與指向型別無關) |
| 陣列型別 | **整個陣列總位元組數** | `int a[10]` → 40 |
| 結構體/類別 | 含填充位元組的總大小 | 依對齊規則計算 |
| 聯合體 | 最大成員大小 (含對齊) | `union {int i; char c[10];}` → 12 (對齊到 4) |
| 空類別 (C++) | 至少 1 (確保不同物件有不同位址) | 1 |
| 函數型別 | **非法** (編譯錯誤) | - |
| 不完整型別 | **非法** (如 `extern int arr[]; sizeof(arr)`) | - |
| 位元欄位 | **非法** | - |
int a[50];
int *p = malloc(50 * sizeof(int));
sizeof(a) // 200 (50 * 4) - 陣列總大小
sizeof(p) // 8 (64位系統指標大小) - 僅指標大小!
// 函數參數退化
void func(int arr[50]) { // 實際為 int *arr
sizeof(arr); // 8 (指標大小),非 200!
}
// 正確傳遞大小
void func2(int *arr, size_t n) { ... }
func2(a, sizeof(a)/sizeof(a[0])); // 傳入元素個數
#pragma pack(4) // 設定最大對齊 4 位元組
struct ALIGN_DEMO {
char c; // offset 0, size 1
// 3 bytes padding
int i; // offset 4, size 4
double d; // offset 8, size 8 (但 pack(4) 強制對齊到 4,實際 offset 8)
short s; // offset 16, size 2
// 2 bytes padding (結構體大小須為最大對齊倍數)
}; // 總大小 20 (pack(4)) 或 24 (預設 8 位元組對齊)
#pragma pack() // 恢復預設
sizeof 看似簡單,實則蘊含 C/C++ 物件模型、記憶體佈局、編譯器實現的核心知識。熟練掌握其規則與陷阱,是寫出正確、可移植、高效程式碼的基本功。