C語言#define的用法
- C語言
- 關注:8.33K次
引導語:預處理器是在真正的編譯開始之前由編譯器調用的獨立程序。以下是本站小編分享給大家的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 語言再學習 -- 運算符與表達式
利用宏參數創建字符串:#運算符
在類函數宏的替換部分中,#符號用作一個預處理運算符,它可以把語言符號轉化為字符串。
- 文章版權屬於文章作者所有,轉載請註明 https://xuezhezhai.com/zh-hk/jsj/cyuyan/3m142.html