我們知道,#define是C/C++中用於宏定義的,一般的理解就是直接將其在程序中替換掉。具體什麼的就不多說了,主要說說容易出錯的幾個點:(筆者也是在各種打擊中偶然收穫的)
題1:下面題目的答案是?(填空題)
#define SQUARE(x) x*x
則 SQUARE( 1+1)的值是多少?
解析:估計大家初學C/C++都會被這樣的題坑過,大致思路是SQUARE(1+1) == SQUARE(2)==2*2 ==4,於是答案爲4.這是最低級的錯誤,錯在哪裏很容易就能看的出。因爲計算機處理的時候,只是簡單的替換,因此,SQUARE(1+1)==1+1 * 1+1==1+1+1 ==3(乘法的優先級高於加法),因此這題的答案是 3 ,而不是4.
但是,如果將題目改成下面這樣:
#define SQUARE(x) ( x)*(x)
則 SQUARE( 1+1)的值是多少?
注意觀察改動的地方,僅僅是添加了兩個括號。但是,就是這兩個括號使得答案變了,SQUARE(1+1) == (1+1)*(1+1)==2*2 ==4,因此答案就是簡單的4.好了,有了上面題目和變種題的鋪墊,我們看下面一個題目:
題2:下面題目的答案是什麼?(自己先想想,答案在頁面的最底端)
#define SQUARE(x) x*x
則 SQUARE( SQUARE(1+1))*2的值是多少?
(A) 6 (B) 10 (C) 18 (D)32
解析:是不是可以這樣想呢?借用上一題的答案SQUARE(1+1) ==3,因此將3代替SQUARE(1+1),就有SQUARE(SQUARE(1+1))*2==SQUARE(3)*2==3*3*2==18,剛好發現答案的選項中有一個18,好開心哦。錯!錯!錯!錯在哪裏?錯在借用了上一題的答案,宏定義不是函數,不能隨便借用的。
只能一步一步的替換,SQUARE(SQUARE(1+1))*2 == SQUARE(1+1*1+1)*2==1+1*1+1*1+1*1+1*2==6,很意外,對吧。不信在機器上試試。
題3:也是一道很詭異的題目。
#define PRINTF(a); printf("#")
int main( )
{
int a = 0;
for(int i=0;i<5;++i)
PRINTF(a+i);
system("pause");
return 0;
}
這題乍一看,也是一個簡單的字符串替換的遊戲。PRINTF(a);無論括號裏的數字是多少,都替換成printf("#") 由於循環了5次,因此程序會連續輸出5個 #,機器上試試才發現完全不是那麼回事。怎麼回事?仔細看宏定義!細心的你也許看到了詭異的地方,就是宏定義的時候分號的位置!
在機器上運行發現,程序的結果是輸出一個 #
原來,在宏定義中,直接將#define PRINTF(a); printf("#") 解釋成 #define PRINTF(a) ;printf("#") 【注意寫法的不同,空格的位置】
也就是說上述程序中,循環體中的語句爲空,替換之後結果爲:
for(int i=0;i<5;++i)
;printf("#");
這樣一來,輸出的結果就很明瞭了。輸出一個#