乍看 sizeof(int)、sizeof(x) 總帶括號,極易誤認為函數呼叫。實則 sizeof 是 C 語言 32 個關鍵字之一,在編譯期由編譯器根據型別直接計算位元組大小,不產生任何執行期指令。
sizeof x、sizeof arr[999999]。sizeof(int),否則編譯錯誤 expected primary-expression before "int"。int arr[10];
printf("%zu\n", sizeof arr[999999999]); // 輸出 4,不會存取越界記憶體
printf("%zu\n", sizeof(printf("hactrox"))); // 輸出 4,"hactrox" 並未被列印
第一例證明 sizeof 僅依據 arr[索引] 的型別(int)決定大小,完全不評估索引運算式。
第二例證明 sizeof 不會實際呼叫函數,而是直接取函數回傳型別(printf 回傳 int)的大小。
#define SIZE_OF_ARRAY (sizeof(array) / sizeof(array[0]))
int array[] = {1,2,3,4,5};
for (int d = -1; d < (SIZE_OF_ARRAY - 1); d++) // 無限迴圈!
printf("%d\n", array[d+1]);
sizeof 回傳 size_t(無號),d 為 int(有號)。比較時 d 隱式轉為無號,-1 變成巨大正數,導致條件永真。
解法:將索引改為 size_t,或在比較前強制轉型 (int)SIZE_OF_ARRAY。
printf("Max unsigned int: %u\n", ~(unsigned int)0);
printf("Max signed int: %d\n", ~(unsigned int)0 >> 1);
利用位元補數特性,無需查閱 limits.h 即可獲得極值。
sizeof 是關鍵字,編譯期決議,零執行期開銷。size_t,參與比較/運算時注意有號/無號隱式轉換。sizeof 計算陣列元素個數、結構體大小,避免硬編碼魔術數字。