首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> 關於C語言

C 語言 sizeof 運算子完整指南:編譯期計算、型別大小、陣列指標陷阱與對齊規則

     編輯:關於C語言

sizeof:編譯期計算型別/物件記憶體佔用位元組數

`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)`)-
位元欄位**非法**-

九大關鍵注意點

  1. 結果型別:`size_t` (通常 `unsigned long` 或 `unsigned long long`),格式化列印用 `%zu` (C99)
  2. 編譯期常數:可用於陣列維度宣告 `int buf[sizeof(struct Header)];`
  3. 不評估運算式:`sizeof(func())` 不呼叫 `func`,僅推導回傳型別大小
  4. 陣列不退化:`sizeof(arr)` 回傳整個陣列大小,**唯有** 作為函數參數時退化為指標
  5. 結構體對齊:編譯器插入填充位元組滿足對齊需求,`#pragma pack(n)` 可調整
  6. 靜態成員不計入:C++ 類別 `static` 資料成員不屬於物件大小
  7. 動態陣列:`int *p = malloc(n*sizeof(int)); sizeof(p)` 回傳指標大小,**非**配置大小
  8. 字串字面常數:`sizeof("abc")` = 4 (含結束符 `\0`),`strlen("abc")` = 3
  9. VLA (C99 可變長度陣列):`sizeof` 在**執行期** 計算 (唯一例外)

經典陷阱與對比


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()   // 恢復預設

常見使用場合

  • 動態記憶體配置:`malloc(n * sizeof(T))`
  • 序列化/網路傳輸:`write(fd, &obj, sizeof(obj))` (注意跨平台對齊差異)
  • 緩衝區大小計算:`char buf[sizeof(ProtocolHeader) + MAX_PAYLOAD];`
  • 泛型程式設計:`sizeof(T)` 在模板中推導型別大小
  • 結構體版本相容:結構體首欄位放 `size_t size` 自描述大小

C++ 特有規則

  • 空類別大小 ≥ 1
  • 虛擬函數/虛擬繼承引入 vptr/vbptr 增加大小
  • `sizeof(*this)` 在建構函數中為當前類別大小 (非衍生類別大小)
  • `alignof(T)` (C++11) 取得型別對齊需求

sizeof 看似簡單,實則蘊含 C/C++ 物件模型、記憶體佈局、編譯器實現的核心知識。熟練掌握其規則與陷阱,是寫出正確、可移植、高效程式碼的基本功。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved