【例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 。
結論:一行只能定義一條宏定義。