1. 程式人生 > >史凱凱的程式設計技術部落格

史凱凱的程式設計技術部落格

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;
}

函式就不同了,函式還需要分配棧空間,在執行函式時都要進行入棧和出棧操作,有的還需要分配堆空間。

巨集所實現的功能有限,而且長程式碼不易讀,但是對於邏輯簡單、程式碼不長、經常使用的功能由巨集來實現是個不錯的選擇