#define 宏是在代碼中不加任何驗證的直接替代,當宏中包含運算符時要在最外層加括號,不然可能會出錯
下面使用一個簡單的例子來驗證一下,代碼中定義一個求兩個數中最大數的宏:
MAX_wrong在外層沒有加括號,MAX_right在外層加了括號
#include<stdlib.h>
#include<stdio.h>
#define MAX_wrong(x,y) x>y?x:y
#define MAX_right(x,y) (x>y?x:y)
int main()
{
int x, y;
scanf("x=%d y=%d", &x, &y);
//下面這行等價於 int a = x>y?x:y*6
int a = MAX_wrong(x,y) * 6;
//下面這行等價於 int a = (x>y?x:y)*6
int b = MAX_right(x,y) * 6;
/*下面這行輸出的兩個結果是一樣的*/
printf("%d %d\n", MAX_wrong(x,y), MAX_right(x,y));
/*當x>y時,a和b值不一樣,當x<=y時,a和b的值一樣*/
printf("%d %d\n", a, b);
return 0;
}
經過下面兩個測試用例,發現不管定義宏時外層加沒加括號,宏MAX_wrong和宏MAX_right的值都是一樣的,沒有問題。
但是要對宏進行運算時出現了問題,下面第一個的測試結果中,a和b的值碰巧一樣;但是第二個測試結果中a和b的值不同,b是我們想要的值,a的值和預想中不一樣。
分析其原因:
int a = MAX_wrong(x,y) * 6; 這句話實際相當於 int a = x>y?x:y* 6;
x>y?x:y* 6 的意思是如果x>y則返回x,否則返回冒號後面的值y*6
而int b = MAX_right(x,y) * 6; 這句話實際相當於 int a = (x>y?x:y) * 6;
括號的優先級要高於*,所以會先計算x>y?x:y的值,再進行*6,與我們想要的一樣。
完畢!