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)在宏定義中的形參是標識符,而宏調用中的實參可以是表達式。
[例93]
#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)帶參函數和帶參宏的區別。
[例94]
#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。