| 概念 | 定義 | 典型值 (x86-32) |
|---|---|---|
| 類型自身對齊值 | 類型要求的地址倍數 | char=1, short=2, int/float/指標=4, double/long long=8 |
| 結構體自身對齊值 | 成員中最大的自身對齊值 | 取決於成員 |
| 指定對齊值 | #pragma pack(n) 設定 | 1,2,4,8,16... |
| 編譯器預設對齊值 | 未指定 pack 時使用 | 通常等於 CPU 字長 (32位=4, 64位=8) |
| 有效對齊值 | min(自身對齊值, 指定/預設對齊值) | 最終決定成員放置位置 |
struct A { char c; short s; int i; };
// c: offset 0 (align 1) → size 1
// s: offset 2 (align 2, 1→2) → size 2
// i: offset 4 (align 4, 3→4) → size 4
// 結尾 8, 結構體 align 4 → 8%4=0 → sizeof=8
#pragma pack(1))#pragma pack(1)
struct PA { char c; short s; int i; };
#pragma pack()
// c:0(1), s:1(1), i:2(1) → 結尾 6, align 1 → sizeof=6
struct B { char c; int i; short s; };
// c:0(1), i:4(4, 1→4), s:8(2) → 結尾 10, align 4 → 12 (補齊 2 字節)
#pragma pack(2))#pragma pack(2)
struct PB { char c; int i; short s; };
#pragma pack()
// c:0(1), i:2(min(4,2)=2), s:6(2) → 結尾 8, align 2 → 8%2=0 → sizeof=8
#include <stdio.h>
struct A { char c; short s; int i; };
#pragma pack(1) struct PA { char c; short s; int i; }; #pragma pack()
struct B { char c; int i; short s; };
#pragma pack(2) struct PB { char c; int i; short s; }; #pragma pack()
int main() {
struct A a; struct PA pa; struct B b; struct PB pb;
printf("sizeof(A)=%zu, &c=%p, &s=%p, &i=%p\n", sizeof(a), &a.c, &a.s, &a.i);
printf("sizeof(PA)=%zu, &c=%p, &s=%p, &i=%p\n", sizeof(pa), &pa.c, &pa.s, &pa.i);
printf("sizeof(B)=%zu, &c=%p, &s=%p, &i=%p\n", sizeof(b), &b.c, &b.s, &b.i);
printf("sizeof(PB)=%zu, &c=%p, &s=%p, &i=%p\n", sizeof(pb), &pb.c, &pb.s, &pb.i);
return 0;
}

#pragma pack(1):雙端協議結構體強制 1 字節對齊,消除編譯器差異int32_t, uint16_t 替代 int, shorthtonl/ntohl, htons/ntohs字節對齊是「空間換時間」的經典權衡。理解 有效對齊值 = min(自身, 指定/預設) 及「結尾向上取整」規則,配合 #pragma pack 與固定寬度類型,即可寫出可移植、高效能的系統級代碼。