当前位置:编程学习 > C/C++ >>

#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++ ,
CopyRight © 2022 站长资源库 编程知识问答 zzzyk.com All Rights Reserved
部分文章来自网络,