核心差異一覽
| 特性 | sizeof | strlen |
| 性質 | 編譯期運算子 | 執行期函數 |
| 參數 | 型別或運算式(不求值) | const char*(必須以 \0 結尾) |
| 回傳 | 型別/物件佔用位元組數(size_t) | 字串長度(不含結束符) |
| 陣列參數 | 不退化,得知完整大小 | 退化為指標,只能算長度 |
| 動態記憶體 | 只能得知指標大小 | 正常運作 |
經典範例解析
char *ss = "0123456789";
sizeof(ss) // 4/8(指標大小)
sizeof(*ss) // 1(char)
char ss[] = "0123456789";
sizeof(ss) // 11(含結束符)
strlen(ss) // 10
char ss[100] = "0123456789";
sizeof(ss) // 100(陣列宣告大小)
strlen(ss) // 10
int arr[100];
sizeof(arr) // 400(100 * sizeof(int))
// strlen(arr) // 編譯錯誤:參數型別不符
進階規則
sizeof 可用於函數呼叫運算式:sizeof(f()) 等於 sizeof(回傳型別),不會呼叫函數。
- 結構體
sizeof 受對齊影響,參考 #pragma pack 或 __attribute__((packed))。
- 函數參數為陣列時(
void fun(char s[20])),實際退化為指標,sizeof(s) 為指標大小。
sizeof 不可用於:函數型別、不完全型別(如未知大小陣列 extern int a[];)、位元欄位、void。
常見用途
- 動態配置:
malloc(n * sizeof(T))
- 記憶體操作:
memset(buf, 0, sizeof(buf))(僅限陣列,非指標)
- 通用資料結構儲存型別大小(如 Windows 結構體的
cbSize 欄位)。
- 編譯期計算陣列元素數:
#define ARRAY_SIZE(a) (sizeof(a)/sizeof((a)[0]))。
避坑指南
- 指標變數永遠不要用
sizeof(ptr) 期望得到指向資料大小。
- 函數參數為陣列時,大小必須額外傳遞參數。
- 結構體對齊導致
sizeof 大於成員大小總和,屬正常現象。