正文 第26章 預處理命令1(2 / 2)

intx,y,max;

printf("inputtwonumbers:");

scanf("%d,%d",&x,&y);

max=MAX(x,y);

printf("max=%d\n",max);

上例程序的第1行進行帶參宏定義,用宏名MAX表示條件表達式(a>b)?a:b,形參a、b均出現在條件表達式中。程序第7行max=MAX(x,y);為宏調用,實參x、y將代換形參a、b。宏展開後該語句為:

max=(x>y)?x:y;

用於計算x,y中的較大數。

對於帶參的宏定義有以下問題需要說明:

(1)帶參宏定義中,宏名和形參表之間不能有空格出現。

例如把:

#defineMAX(a,b)(a>b)?a:b

寫為:

#defineMAX(a,b)(a>b)?a:b

將被認為是無參宏定義,宏名MAX代表字符串(a,b)(a>b)?a:b。宏展開時,宏調用語句:

max=MAX(x,y);

將變為:

max=(a,b)(a>b)?a:b(x,y);

這顯然是錯誤的。

(2)在帶參宏定義中,形式參數不分配內存單元,因此不必作類型定義。而宏調用中的實參有具體的值,要用它們去替換形參,則必須作類型說明。這與函數中的情況不同。在函數中,形參和實參是兩個不同的量,各有自己的作用域,調用時要把實參值賦予形參,進行值傳遞。而在帶參宏中,隻是符號代換,不存在值傳遞的問題。

(3)在宏定義中的形參是標識符,而宏調用中的實參可以是表達式。

[例93]

#defineCUBE(y)(y)*(y)*(y)

voidmain()

inta,cube;

printf("inputanumber:");

scanf("%d",&a);

cube=CUBE(a+1);

printf("cube=%d\n",cube);

上例中第1行為宏定義,形參為y。程序第7行宏調用中實參為a+1,是一個表達式,在宏展開時,用a+1替換y,再用(y)*(y)*(y)替換CUBE,得到如下語句:

cube=(a+1)*(a+1)*(a+1);

這與函數的調用是不同的,函數調用時要把實參表達式的值求出來再賦予形參,而宏替換中對實參表達式不作計算而是直接按照原樣進行替換。

(4)在宏定義中,字符串內的形參通常要用括號括起來以避免出錯。在上例中的宏定義中(y)*(y)*(y)表達式的y都用括號括起來,因此結果是正確的。如果去掉括號,把程序改為以下形式:

#defineCUBE(y)y*y*y

voidmain()

inta,cube;

printf("inputanumber:");

scanf("%d",&a);

cube=CUBE(a+1);

printf("cube=%d\n",cube);

運行結果為:

inputanumber:3

cube=10

同樣輸入3,但結果卻是不一樣的。這是由於宏替換隻作符號替換而不作其他處理而造成的。宏替換後將得到以下語句:

cube=a+1*a+1*a+1;

由於a為3故cube的值為10。這顯然與題意相違,因此參數兩邊的括號是不能少的。

(5)帶參函數和帶參宏的區別。

[例94]

#defineMC(m)2*m

#defineMB(n,m)2*MC(n)+m

voidmain()

inti=2,j=3;

printf("%d\n",MB(j,MC(i)));

則作宏替換時,先將MC(i)替換為2*i,再將MB(j,2*i)替換為2*2*j+2*i結果為16。