【例7.5】下面是一个输出2倍乘法口诀的程序,找出其错误之处并改正之。
#include <stdio.h> #define DOUBLE (value ) ((value )+ (value )) void main ( ) { int i ; for (i=1 ;i<=10 ;i++ ) printf ("%d*2=%d\n" ,i ,DOUBLE (i )); }
“DOUBLE”与“(value)”之间留有空格,变成把DOUBLE定义成
(value ) ((value )+ (value ))
的形式,所以编译器无法对DOUBLE的定义进行解释。只要将它改为
#define DOUBLE (value ) ((value )+ (value ))
即可。也可以采用如下方法。
#include <stdio.h> #define DOUBLE (x ) ((x )*2 ) void main () { int i ; for (i=1 ;i<11 ;i++ ) printf ("%d*2=%d\n" ,i ,DOUBLE (i )); }
同样,要注意“DOUBLE”与“(x)”之间不能有空格。
结论:要重视定义宏时,那些地方必须有空格,而那些地方不能有空格。
【例7.6】下面程序的ABS(2-5)计算为-7,分析错在何处。
#include <stdio.h> #define ABS (x ) x>0 ?x :-x void main () { printf ("%d\n" ,ABS (2-5 )); }
从写法上看,似乎没有错误。如果将“2-5”展开,可以得到:
2-5>0 ?2-5 :-2-5
展开时没有达到预想的“-(2-5)=-2+5=3”。
如果要达到次目的,需要将参数括起来,即
#define ABS (x ) (((x )>0 )?(x ):- (x ))
展开得到
(2-5 )>=0 ?(2-5 ):- (2-5 )
结论:在宏定义中最好将每个参数都用括号括起来以预防引起与优先级有关的问题。同样,整个结果表达式也应该用括号括起来,以防止当宏用于一个更大一些表达式中可能出现的问题。
上述程序修改为如下的演示程序。
#include <stdio.h> #define ABS (x ) (((x )>0 )?(x ):- (x )) void main () { printf ("2-5=%d ,3-3=%d ,5-2=%d\n" ,ABS (2-5 ),ABS (3-3 ),ABS (5-2 )); printf ("-7=%d ,0=%d ,15=%d\n" ,ABS (-7 ),ABS (0 ),ABS (15 )); }
输出结果如下。
2-5=3 ,3-3=0 ,5-2=2 -7=7 ,0=0 ,15=15
【例7.7】分析下面程序的错误并改正之。
#include <stdio.h> #define R2 (a ) (a*a ) #define R3 (a ) (a*a*a ) void main () { int a=5 ; printf ("%d 的平方等于%d ,%d 的立方等于%d 。\n" ,a ,R2 (a ),a ,R3 (a )); }
一行可以写多个C语言的语句,但宏定义不是C语言的语句,所以一行只能定义一个宏定义。即改为
#define R2 (a ) (a*a ) #define R3 (a ) (a*a*a )
即可。运行结果如下。
5 的平方等于25 ,5 的立方等于125 。
结论:一行只能定义一条宏定义。