#define宏定义的陷阱
我们知道,#define是C/C++中用于宏定义的,一般的理解就是直接将其在程序中替换掉。具体什么的就不多说了,主要说说容易出错的几个点:(笔者也是在各种打击中偶然收获的)
题1:下面题目的答案是?(填空题)
[cpp]
#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.
但是,如果将题目改成下面这样:
[cpp]
#define SQUARE(x) ( x)*(x)
则 SQUARE( 1+1)的值是多少?
注意观察改动的地方,仅仅是添加了两个括号。但是,就是这两个括号使得答案变了,SQUARE(1+1) == (1+1)*(1+1)==2*2 ==4,因此答案就是简单的4.
好了,有了上面题目和变种题的铺垫,我们看下面一个题目:
题2:下面题目的答案是什么?(自己先想想,答案在页面的最底端)
[cpp]
#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:也是一道很诡异的题目。
[cpp]
#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("#") 【注意写法的不同,空格的位置】
也就是说上述程序中,循环体中的语句为空,替换之后结果为:
[cpp]
for(int i=0;i<5;++i)
;printf("#");
这样一来,输出的结果就很明了了。输出一个#
补充:软件开发 , C++ ,