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

C語言結構體大小計算詳解:對齊規則、填充字節與實戰驗證

     編輯:關於C語言

核心概念:偏移量與對齊

  • 偏移量:成員地址相對結構體首地址的字節差。
  • 對齊原則(兩種等價表述):
    1. 成員偏移量必須是該成員大小的整數倍(0 視為任意倍數)。
    2. 結構體總大小必須是最寬基本類型成員大小的整數倍。
  • 編譯器在成員間、末尾插入填充字節以滿足對齊。

三個驗證案例(32位系統,4字節對齊)

struct A { int a; char b; int c; };      // sizeof = 12
struct B { char b; int a; int c; };      // sizeof = 12
struct C { int a; char b; short c; long long d; int e; }; // sizeof = 24

逐案例內存佈局圖解

結構體 A:int a; char b; int c;

偏移 0-3  : a (int, 4字節)
偏移 4    : b (char, 1字節)
偏移 5-7  : 【填充 3 字節】← 使 c 對齊到 4 的倍數
偏移 8-11 : c (int, 4字節)
總大小 12 :已是 4 的倍數,無尾部填充

結構體 B:char b; int a; int c;

偏移 0    : b (char, 1字節)
偏移 1-3  : 【填充 3 字節】← 使 a 對齊
偏移 4-7  : a (int)
偏移 8-11 : c (int)
總大小 12

雖然成員順序不同,但受最寬類型 (int=4) 制約,最終大小相同。成員重排可減少填充(如將 char 移到末尾)。

結構體 C:作者疑惑案例

成員序列:int(4) | char(1) | short(2) | long long(8) | int(4)
最寬類型:long long (8字節) → 結構體大小須 8 的倍數

偏移計算:
0-3   : int a (4)
4     : char b (1)
5     : 【填充 1】→ short c 對齊到 2 的倍數 (偏移 6)
6-7   : short c (2)
8-15  : long long d (8) ← 已自然對齊到 8 的倍數
16-19 : int e (4)
20-23 : 【尾部填充 4】→ 總大小 24 (8的倍數)

作者原文表格中「偏移 5 填充 1」後接 short (偏移 6),再接 long long (偏移 8) 完全吻合。最終 24 字節符合規則。

實用技巧:offsetof 宏與手動控制

#include <stddef.h>
printf("offset of c = %zu\n", offsetof(struct A, c));  // 標準庫獲取偏移
  • #pragma pack(n) / __attribute__((packed)):壓縮結構體(犧牲訪問速度換空間)。
  • 嵌入式/網絡協議常用 packed + 手動填充保證跨平台一致性。

總結口訣

  1. 找最寬基本類型 → 決定結構體對齊基數。
  2. 按聲明順序依次放置,每個成員向上對齊到自身大小倍數。
  3. 最後總大小向上取整到基數倍數。
  4. 調整成員順序(大類型優先)可極大減少填充。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved