在 C 語言中使用帶參數的宏定義時,有時會遇到意想不到的結果。例如以下代碼在 VS2013 中編譯無錯,但輸出卻是 0.000000:
#include <stdio.h>
#define FUNC(X,Y) (1/(X)+1/(Y))
int main(void) {
double x = FUNC(2,2);
printf("%lf\n", x);
return 0;
}
C 語言中,當兩個整數進行除法運算時,結果仍為整數,小數部分會被直接截斷(向零取整)。在宏展開後,1/(2) 實際上是 1/2,兩者均為 int 型別,結果為 0。因此 0 + 0 = 0,最終賦值給 double 變數時顯示為 0.000000。
將除數或被除數至少一方改為浮點數字面量,強制編譯器進行浮點運算:
#define FUNC(X,Y) (1.0/(X) + 1.0/(Y))
此時 1.0 為 double 型別,根據隱式型別轉換規則,整數參數會被提升為 double,運算結果自然保留小數部分。
.0 或 f 後綴。(X)、(Y),防止運算符優先級導致邏輯錯誤。inline 函數或模板,避免宏帶來的副作用。宏定義本質是文本替換,不具備型別檢查能力。理解整數除法特性,並在常量中明確指定浮點型別,是避免此類低級錯誤的關鍵。