史凱凱的程式設計技術部落格
1.1 巨集定義
C語言標允許在程式中用一個標識來表示一個字串,稱為巨集。識別符號為巨集名,在編譯預處理時,將程式中所有的巨集名用相應的字串來替代,這個過程稱為巨集替換,巨集分為無引數的巨集和有引數的巨集。
【例1】使用無引數巨集的程式,輸入半徑,求圓的周長、面積、和體積。
1 #include <stdio.h>
2 #define PI 3.1415926
3 main()
4 {
5 float 1,s,r,v;
6 printf("input radius:");
7 scanf("%f",&r);
8 1=2.0*PI*r;
9 s=PI*r*r;
10 v=4.0/3.0*PI*r*r*r;
11 printf("1=%10.4f\ns=%10.4f\nv=%10.4f\n",1,s,v);
12 }
【例2】輸入格式為巨集的示例。
1 #define PRprintf
2 #define NL"\n"
3 #define MACRO "%d"
4 #define MACRO1 NL
5 #define MACRO2 MACRO NL
6 #define MACRO3 MACRO MACRO NL
7 #define MACRO4 MACRO MACRO MACRO NL
8 #define S"%s\n"
9 main()
10 {
11 int a,b,c,d;
12 char string[]="CHINA";
13 A=1;B=2;C=3;D=4;
14 PR(MACRO1,a);
15 PR(MACRO2,a,b);
16 PR(MACRO3,a,b,c);
17 PR(MACRO4,a,b,c,d);
18 PR(s,string);
19 }
2.有引數巨集
類似於有引數的函式,其定義的一般形式為:
#define MAX(x,y) (x>y? X:y)
main()
{
int a=1,b=2,max;
max=MAX(a,b);
printf{"the max between(%d,%d)is%d\n",a,b,max}
}
程式說明:
#define M(x,y) x*y
在程式中有:
int a=2,b=3,c;
c=M(a+1,b+1);
那麼進行巨集替換,a+1是x的實參,b+1是y的實參,那麼替換後的結果為:
c=a+1*b+1;
顯然這是不符合要求的,應該按照如下方式進行巨集定義:
#define M(x,y)(x)*(y)
此時的巨集展開後:
c=(a=1)*(b+1);
定義有引數的巨集的時候,應該注意。
(1)巨集名與形參的圓括號之間不能有空格,否則會導致錯誤。例如#define M(x,y)(x)*( y ),M與“(”之間不能有空格。
(2)在巨集定義中,字串內的形式引數最好用括號括起來,以免錯誤。例如,#defineM(x,y)(x)(y)、x、y都用括號括起來。
巨集定義與函式的區別
巨集只是字元的替換,在預處理階段就給替換到程式碼中去了比如下面的程式碼 #include<stdio.h> #define MAX(x, y) ((x)>(y)?(x):y()) int main() { int a = 2, b = 4; int m; m = MAX(2, 4); printf("%d\n", m); return 0; } 如果你用的是gcc編譯器,執行 gcc -E main.c -o main.i,開啟main.i檔案就可以看到他是如何替換進去的,直接拖到最後,前面的都是stdio.h中的內容。 int main() { int a = 2, b = 4; int m; m = ((2)>(4)?(2):4()); printf("%d\n", m); return 0; } 函式就不同了,函式還需要分配棧空間,在執行函式時都要進行入棧和出棧操作,有的還需要分配堆空間。 巨集所實現的功能有限,而且長程式碼不易讀,但是對於邏輯簡單、程式碼不長、經常使用的功能由巨集來實現是個不錯的選擇