C語言#define的用法

引導語:預處理器是在真正的編譯開始之前由編譯器調用的獨立程序。以下是本站小編分享給大家的C語言#define的用法,歡迎閱讀!

C語言#define的用法

 #define的用法

#define 是一個預處理指令,這個預處理執行可以定義宏。與所有預處理指令一樣,預處理指令#define用#符號作爲行的開頭。預處理指令從#開始,到其後第一個換行符爲止。也就是說,指令的長度限於一行代碼。如果想把指令擴展到幾個物理行,可使用反斜線後緊跟換行符的方法實現,該出的換行符代表按下回車鍵在源代碼文件中新起一行所產生的字符,而不是符號 n 代表的字符。在預處理開始錢,系統會刪除反斜線和換行符的組合,從而達到把指令擴展到幾個物理行的效果。可以使用標準C註釋方法在#define行中進行註釋。

//使用反斜線+回車

#define OW "hello

world!" /*注意第二行要左對齊*/

每一個#define行由三部分組成:

第一部分,指令#deine自身。

第二部分,所選擇的縮略語,這些縮略語稱爲宏(分爲對象宏和函數宏)。宏的名字中不允許有空格,而且必須遵循C變量命名規則:只能使用字母、數字和下劃線(_),第一個字符不能爲數字。習慣上宏名用大寫字母表示,以便於與變量區別。但也允許用小寫字母。

第三部分,(#define行的其餘部分)稱爲替換列表或主體。

注意,結尾沒有分號

下面來看一個例子:

#include

#define OW 2 * 2

#define OW 2 * 2

//#undef OW 需要先取消宏定義

#define OW 2*2

int main (void)

{

printf ("%dn", OW);

return 0;

}

輸出結果:

define.c:5:0: 警告: “OW”重定義 [默認啓用]

define.c:4:0: 附註: 這是先前定義的位置

相同定義意味着主體具有相同順序的語言符號。因此,下面兩個定義相同:

#define OW 2 * 2

#define OW 2 * 2

兩者都有三個相同的語言符號,而且額外的`空格不是主體的一部分。下面的定義則被認爲是不同的:

#define OW 2*2

上式只有一個(而非三個)語言符號,因此與前面兩個定義不同。可以使用#undef指令重新定義宏。

宏所代表的數字可以在編譯命令中指定(使用-D選項)

/*

宏演示

*/

#include

int main()

{

int num=0;

int arr[SIZE]={}; //使用gcc -D可以宏定義這個數字

for(num = 0;num <= SIZE - 1;num++)

{

arr[num]=num;

printf("%d ",arr[num]);

}

printf("n");

return 0;

}

gcc -DSIZE=4 define.c

輸出結果:

0 1 2 3

函數宏:

通過使用參數,可以創建外形和作用都與函數相似的類函數宏。宏的參數也用圓括號括起來。類函數宏的定義中,用圓括號括起來一個或多個參數,隨後這些參數出現在替換部分。

#include

#define SQUARE(X) X*X

#define PR(X) printf ("The result is %dn", X)

int main (void)

{

int x = 4;

int z;

printf ("x = %dn", x);

z = SQUARE(x);

printf ("Evaluating SQUARE(x): ");

PR(z);

z = SQUARE(2);

printf ("Evaluating SQUARE(2): ");

PR(z);

printf ("Evaluating 100/SQUARE(2): ");

PR(100/SQUARE(2));

z = SQUARE(x+2);

printf ("Evaluating SQUARE(x+2): ");

PR(z);

printf ("x is %dn", x);

z = SQUARE(++x);

printf ("Eavluating SQUARE(++x): ");

PR(SQUARE (++x));

printf ("After incrementing, x is %xn", x);

return 0;

}

輸出結果:

x = 4

Evaluating SQUARE(x): The result is 16

Evaluating SQUARE(2): The result is 4

Evaluating 100/SQUARE(2): The result is 100

Evaluating SQUARE(x+2): The result is 14

x is 4

Eavluating SQUARE(++x): The result is 36

After incrementing, x is 6

SQUARE(x+2) 輸出結果是14,而不是想要的6*6 = 36。這是因爲預處理器不進行計算,而只進行字符串替換。在出現x的地方,預處理都用字符串 x+2進行替換。x*x 變爲 x+2*x+2 根據運算符優先級,則結果爲 14

100/SQUARE(2)輸出結果是 100,而不是想要的 25。因爲,根據優先級規則,表達式是從左到右求值的。

100/2*2 = 100

要處理前面兩個示例中的情況,需要如下定義:

#define SQUARE(x) ((x) * (x))

從中得到的經驗是使用必須的足夠多的圓括號來保證以正確的順序進行運行和結合。

SQUARE(++x) 根據編譯器的不同會出現兩種不同的結果。解決這個問題的最簡單的方法是避免在宏的參數中使用++x。一般來說,在宏中不要使用增量或減量運算符。

參看:C 語言再學習 -- 運算符與表達式

利用宏參數創建字符串:#運算符

在類函數宏的替換部分中,#符號用作一個預處理運算符,它可以把語言符號轉化爲字符串。