sizeof 是 C 語言中的一元操作符(而非函數),用於在編譯期確定類型或表達式的存儲大小(以字節為單位)。其結果類型為 size_t(通常為 unsigned int 或 unsigned long)。掌握 sizeof 的行為細節,對於內存管理、序列化、跨平台移植及性能優化至關重要。
sizeof(int)、sizeof(struct Foo) —— 必須加括號。sizeof variable、sizeof arr[0] —— 變量名可不加括號,但加上也無妨。sizeof(i++) 不會修改 i)。char、signed char、unsigned char:恆為 1(C 標準保證)。short、int、long、long long、浮點類型:實現定義,常見於 32/64 位系統的差異(如 long 在 Windows 64 位為 4 字節,Linux 64 位為 8 字節)。void、不完全類型(未知大小數組、前向聲明的結構體)、位域:禁止使用,編譯報錯。sizeof(T*) 等於平台指針大小:32 位系統通常為 4,64 位系統通常為 8。與指向的類型 T 無關。
int a[10]; sizeof(a) == 10 * sizeof(int) —— 獲得整個數組大小,不退化為指針。int *p = malloc(10*sizeof(int)); sizeof(p) == sizeof(int*);函數參數 void f(int a[]) 實際為指針,sizeof(a) 返回指針大小。sizeof(struct S) ≥ 成員大小之和。sizeof == 0;C++ 中為 1。size_t,無符號,格式化輸出用 %zu(C99)或 %lu 配合強轉。#if 預處理條件(配合常量表達式)。sizeof(int) ✓,sizeof int ✗。sizeof 返回整體大小,其他上下文(如傳參、賦值)才退化為指針。#pragma pack(n)、編譯器屬性 __attribute__((packed)) 影響,跨平台傳輸需显式處理。sizeof 在運行時求值(僅此例外),sizeof(int[n]) 依賴 n 的運行時值。sizeof("abc") == 4(含結束符 \0),不同於 strlen("abc") == 3。sizeof(bf) 非法,需用 sizeof(struct) 間接獲取。sizeof(func) 非法,函數無存儲大小概念。malloc(n * sizeof(Type)) 避免硬編碼類型大小。#pragma pack(1) 計算線上大小,或使用 offsetof 手動布局。#define ARRAY_SIZE(arr) (sizeof(arr)/sizeof((arr)[0])) 僅適用於靜態數組作用域內。_Static_assert(sizeof(int) == 4, "int must be 32-bit");(C11)。fwrite(buf, sizeof(*buf), count, fp) 自動適配元素大小。// 錯誤:形參數組退化為指針
void foo(int arr[100]) {
sizeof(arr); // 返回 4 或 8,而非 400
}
// 正確:傳遞長度或使用結構體包裹
void bar(int *arr, size_t len) { ... }
struct Wrapper { int data[100]; };
void baz(struct Wrapper w) { sizeof(w.data); // 400 }
總結:sizeof 是靜態類型系統的鏡像,正確理解其編譯期語義、對齊規則與退化例外,是編寫健壯、可移植 C 代碼的基礎功力之一。