首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 更多程式語言 >> 程式設計疑難解答

C 宏展開陷阱:10*MIN(i,j) 實為 (10*i)
     編輯:程式設計疑難解答

代碼

#define MIN(x,y) (x)<(y)?(x):(y)
int i=10, j=15, k;
k = 10 * MIN(i, j);
printf("%d", k); // 輸出 15

展開過程

  1. 宏替換:k = 10 * (i) < (j) ? (i) : (j);
  2. 運算符優先級:**乘法 > 關係運算 > 三元運算**。
  3. 等價於:k = (10 * i) < j ? i : j;
  4. 10*10=100 < 15 為假,取 j=15。

修正宏定義

#define MIN(x,y) ((x)<(y)?(x):(y))   // 外層加括號
// 或更安全
#define MIN(x,y) ({ typeof(x) _x=(x); typeof(y) _y=(y); _x<_y?_x:_y; }) // GNU C 擴展

教訓

  • 宏參數**必須加括號**,宏整體**必須加括號**。
  • C++ 推薦用 inline constexpr 函數/模板替代宏,享受類型安全與作用域。

宏展開看優先級,外層括號少不了,C++ 改用 inline 函數更安心。

  1. 上一篇文章:
  2. 下一篇文章:

Copyright © 程式碼之家 All Rights Reserved