1. 程式人生 > >C++中巨集定義的使用注意事項

C++中巨集定義的使用注意事項

1 簡介

巨集定義C語言的三種預處理功能之一,另外兩種預處理是檔案包含和條件編譯。

1.1 格式

巨集定義的格式分為不帶引數和帶引數兩種。

不帶引數的格式為

#define 巨集名 字串

帶引數的格式為

#define 巨集名(引數表) 字串

1.2 使用

巨集展開是在預處理階段完成的,這個階段把巨集名只是看作一個字串,並不會有任何的計算髮生展開時在巨集出現的地方只是簡單地使用串來代替,並不會增添任何的符號。

2 使用時的注意事項

2.1 使用帶引數的巨集定義時,要使用完備的括號

由於巨集定義只是簡單的字元替換,巨集的引數如果是複合結構,如果不使用括號,可能會產生意想不到的情況。如

#define ADD(a, b) a+b

或者

#define ADD(a, b) (a)+(b)

此時如果要計算ADD(a,b)*ADD(a,b),則會變成

a+b*a+b

或者

(a)+(b)*(a)+(b)

因此,對於巨集定義要使用完備的括號

#define ADD(a, b) ((a)+(b))

2.2 使用巨集定義時,不允許引數發生變化

如果在使用巨集定義時,引數進行了自增或者自減變化,則在巨集定義展開時對其引數的多次自增或自減變化,導致意想不到的情況。如

#define SQUARE(a) ((a)*(a))

int nValue = 10;

int nSquare = SQUARE(nValue++);

此時,nSquare的值是

110,而nValue的值是12

所以,為了避免出現這種情況,最簡單有效的方法是保證巨集定義的引數不發生變化。

2.3 用大括號將巨集定義的多條表示式括起來

如果巨集定義包含多條表示式,一定要用大括號將其括起來。如果沒有這個大括號,巨集定義中多條表示式很可能只有一條會被執行。

#define INIT(a, b, c) a=0;b=1;c=2;

for(int i=0; i<10; ++i)

  INIT(A[i].a, B[i].b, C[i].c);

簡單的字元代替,for迴圈變為

for(int i=0; i<10; ++i)

  A[i].a = 0;

B[i].b = 1;

C[i].c = 2;

此時,程式會因為i超出作用域範圍而報錯。如果把INIT巨集寫成

#define INIT(a, b, c) {a=0;b=1;c=2;}

則可以完成對ABC陣列的初始化。