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

C語言結構體與聯合體深度解析:記憶體對齊與大小計算

     編輯:關於C語言

結構體基本定義

// 僅定義類型,不配置記憶體
struct student {
    int num;
    char name[20];
};

變量定義與大小驗證

struct student stu;
printf("struct size: %lu\n", sizeof(stu));   // 24
printf("int size: %lu\n", sizeof(int));       // 4
printf("char[20] size: %lu\n", sizeof(char[20])); // 20

4 + 20 = 24,符合預期。

記憶體對齊陷阱

案例 1:插入 char sex

struct student {
    int num;      // 4 bytes
    char sex;     // 1 byte
    char name[20]; // 20 bytes
};
sizeof(stu) = 28  // 而非 4+1+20=25

原因:編譯器按 4 位元組對齊。sex 後需填充 3 位元組,使 name 起始位址為 4 的倍數。

案例 2:調整成員順序

struct student {
    char name[23]; // 23 bytes
    int num;       // 4 bytes
    char sex;      // 1 byte
};
sizeof = 32  // 23 -> 對齊到 24, +4 = 28, +1 -> 對齊到 32

結構體總大小必須是最大成員大小的整數倍(此處為 4),方便陣列存取。

優化技巧:重新排序成員

struct student_opt {
    int num;       // 4
    char sex;      // 1
    char name[20]; // 20
    // 共 24,sex 緊湊在 num 後,name 自然對齊
};

將大型別、對齊要求高的成員放前面,小型別放中間或利用空隙,可減少填充位元組。

聯合體

union data {
    int i;
    float f;
    char str[20];
};
  • 所有成員共用同一塊記憶體,大小 = 最大成員大小(此處 20 位元組)。
  • 同一時間只能存取一個成員,寫入 i 後讀取 f 為未定義行為(除非用於型別雙關)。
  • 常用於:省記憶體、實現變體記錄、網路協議封包解析。

實務建議

  1. 使用 offsetof 宏檢查成員偏移:offsetof(struct student, name)。
  2. 若需精確控制對齊,可用 #pragma pack(n) 或 GCC __attribute__((packed)),但可能降低存取效能。
  3. 結構體傳參建議用指標,避免大量複製開銷。
  4. 聯合體搭配結構體實現「標籤聯集」:
struct packet {
    int type;      // 0=int, 1=float, 2=string
    union data payload;
};

理解記憶體對齊與聯合體特性,是編寫高效、可移植 C 程式的關鍵進階技能。

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