sizeof 是 C/C++ 筆試面試的高頻考點,看似簡單卻暗藏玄機。本文系統梳理 sizeof 的核心規則、基本類型大小、指針與數組的區別、結構體內存對齊規則,並通過實測代碼驗證結論。
sizeof(type) 或 sizeof expressionsize_t(無符號整數)| 類型 | 大小 (bytes) | 備註 |
|---|---|---|
| char / signed char / unsigned char | 1 | 定義為 1 字節 |
| short / short int | 2 | |
| int | 4 | 32 位系統通常 4 字節 |
| long / long int | 4 | 32 位系統通常 4 字節 |
| long long | 8 | C99/C++11 |
| float | 4 | IEEE 754 單精度 |
| double | 8 | IEEE 754 雙精度 |
| long double | 12/16 | 實現相關,常為 12 或 16 |
| 指針 (T*) | 4 | 32 位系統地址寬度 |
注意: C 標準僅保證 sizeof(char) == 1 及 sizeof(short) <= sizeof(int) <= sizeof(long),具體大小由實現定義(ABI)。64 位系統下指針與 long 通常為 8 字節。
char str[] = "ABC"; // 數組,大小 4 (含 '\0')
char* p = str; // 指針,大小 4 (32位) / 8 (64位)
sizeof(str); // 4 —— 數組類型包含長度信息
sizeof(p); // 4/8 —— 指針類型只存地址
sizeof(*p); // 1 —— 解引用得到 char
核心區別: 數組類型編碼了長度,指針類型不包含長度信息。函數參數中數組退化為指針,sizeof 失效。
結構體大小**不等於**成員大小之和,編譯器為了 CPU 訪問效率,會插入填充字節(padding)。
// 結構體 A:double(8) + char(1) + int(4)
struct A {
double d; // offset 0, size 8
char c; // offset 8, size 1
int i; // offset 12 (需 4 對齊), size 4
}; // 總大小 16 (8+1+3填充+4)
// 結構體 B:char(1) + double(8) + int(4)
struct B {
char c; // offset 0, size 1
double d; // offset 8 (需 8 對齊, 填充 7), size 8
int i; // offset 16, size 4
}; // 總大小 24 (1+7填充+8+4+4尾部填充)
結論: 將大類型(double、long long)放在前面,小類型放後面,通常能減少填充,縮小結構體體積。
#include
#include
struct Str1 { double d; char c; int i; };
struct Str2 { char c; double d; int i; };
int main() {
short sa = 10; int a = 10; long la = 10;
float f = 20; double d = 20; char ch = 'c';
char str[] = "ABC"; char* p = str;
struct Str1 s1; struct Str2 s2;
printf("sizeof(short): %zu\n", sizeof(sa)); // 2
printf("sizeof(int): %zu\n", sizeof(a)); // 4
printf("sizeof(long): %zu\n", sizeof(la)); // 4
printf("sizeof(float): %zu\n", sizeof(f)); // 4
printf("sizeof(double): %zu\n", sizeof(d)); // 8
printf("sizeof(char): %zu\n", sizeof(ch)); // 1
printf("sizeof(str[]): %zu\n", sizeof(str)); // 4
printf("sizeof(p): %zu\n", sizeof(p)); // 4 (32位)
printf("sizeof(*p): %zu\n", sizeof(*p)); // 1
printf("sizeof(Str1): %zu\n", sizeof(s1)); // 16
printf("sizeof(Str2): %zu\n", sizeof(s2)); // 24
return 0;
}
sizeof(int) vs sizeof(long):32 位系統通常相同,64 位系統 long 可能為 8void f(int arr[]) 等價於 void f(int* arr),sizeof(arr) 返回指針大小malloc 返回指針,sizeof(ptr) 無法獲取分配大小struct { char c; } 大小為 1,但 struct { char c; double d; } 大小為 16 而非 9#pragma pack(n) 可改變對齊數,但可能導致非對齊訪問性能下降或硬件異常sizeof(變量) 而非 sizeof(類型),避免類型變更時忘記更新#pragma pack(1) 可壓縮結構體,但需確認 CPU 支持非對齊訪問