讀古今文學網 > C語言解惑 > 15.3 正確定義宏的參數 >

15.3 正確定義宏的參數

【例15.4】運行如下程序得到一個奇怪的輸出結果。請問原因何在?


#include <stdio.h>
#define DOUBLE
(x
) 
(2*x
)
void main
()
{
      int i
;
      for
(i=0
;i<5
;i++
)
             printf
("2*%d = %d\n"
,i+1
,DOUBLE
(i+1
));
}
2*1 = 1
2*2 = 3
2*3 = 5
2*4 = 7
2*5 = 9
  

DOUBLE(1)展開為2*1=2,DOUBLE(i+1)展開為2+i,也就是說,C編譯看到這個代碼首先是將1乘以2,然後再加上i,所以就得到如上結果。

再使用宏時,最好能與定義的格式一樣,以免達不到預定目的。例如在這個程序中,如果使用如下格式:


for
(i=1
;i<6
;i++
)
      printf
("2*%d = %d\n"
, i
, DOUBLE
(i
));
  

就會得到如下的正確輸出:


2*1 = 2
2*2 = 4
2*3 = 6
2*4 = 8
2*5 = 10
  

當然,也可以將宏定義修改為:


#define  DOUBLE
(x
)  
(2*
(x
))
  

這就保證DOUBLE(i+1)展開為2*i+2*1=2(i+1)。

結論:在宏定義中最好將每個參數都用括號括起來以預防引起與優先級有關的問題。同樣,整個結果表達式也應該用括號括起來,以防止當宏用於一個更大一些表達式中可能出現的問題。

可以用「#」號說明要把緊跟它的參數作為字符輸出,例如#x,#表示將參數x轉換成字符串輸出,而不是作為數值輸出。假設用k=5作為參數,則在執行宏


#define  PRINT
(x
)  printf
(#x"=%d\n"
,x
)
  

時,輸出「k=5」。執行宏


#define  PRINT
(x
)  printf
("<debug >" #x "=%d\n"
,x
)
  

時,則輸出「<debug>k=5」。這種方法常用來作為調試程序時的輸出參考信息。

【例15.5】使用宏定義輸出語句演示兩重循環的執行過程。


#include <stdio.h>
#define PRINT
(x
) printf
(#x"=%d\n"
,x
)
void main
()
{
      int i=0
,j=0
;
      for
(i=0
;i<2
;i++
)
      {
           PRINT
(i
);
           for
(j=0
;j<2
;j++
)
             PRINT
(j
);
      }
}
  

程序輸出結果如下。


i=0
j=0
j=1
i=1
j=0
j=1
  

程序演示了每當i循環一次,j則要相應地循環2次的過程。