C語言中巨集定義與使用分析

2021-08-19 04:24:28 字數 3175 閱讀 3640

--事物的難度遠遠低於對事物的恐懼!

這個章節我們來談一談c語言中的巨集定義與使用分析,相信每個學過c的都知道,在c中,巨集具有如下三個特性:

-#define是預處理器處理的單元實體之一

-#define定義的巨集可以出現在 程式的任意位置

-#define定義之後的**都可以使用這個巨集

而在c語言中,我們常常用#define來定義巨集常量,#define定義的巨集常量可直接,其本質為字面量,所以巨集常量是不占用記憶體空間的(const定義的唯讀變數是占用記憶體空間的)。下邊來看看幾個巨集常量的定義,正確嗎?

#define error -1

#define path1 "d:\test\test.c"

#define path2 d:\test\test.c

#define path3 d:\test\

test.c

int main()

首先我們用預處理器來預處理一下,預處理通過(因為預處理是不進行語法檢查的),並且得到的預處理檔案內容如下,從預處理檔案得知,main函式裡的巨集都被具定義的內容所替換。

#line 1 "21-1.c"

int main()

所以說,上邊的四個巨集定義是正確的,能通過預處理器,但是path2餘path3不能通過編譯,因為語法不符(大家可自行實驗)

說完了巨集常量,我們來說說巨集表示式 

-#define表示式的使用類似於函式呼叫

-#define表示式可以比函式更強大

-#define表示式比函式更容易出錯

下邊來看看幾個巨集表示式,執行結果是否正確:

#include #define _sum_(a, b) (a) + (b)

#define _min_(a, b) ((a) < (b) ? (a) : (b))

#define _dim_(a) sizeof(a)/sizeof(*a)

int main()

;    int s1 = _sum_(a, b);    

int s2 = _sum_(a, b) * _sum_(a, b);

int m = _min_(a++, b);

int d = _dim_(c);    

printf("s1 = %d\n", s1);

printf("s2 = %d\n", s2);

printf("m = %d\n", m);

printf("d = %d\n", d);

return 0;

}

好了,我們來編譯執行一下

從執行結果,我們知道s2、m的輸出結果與我們所預期的不一樣,為什麼會是這樣?別急,我們先來看看預處理後的檔案,如下:

#line 1 "21-2.c"

int main()

; int s1 = (a) + (b);

int s2 = (a) + (b) * (a) + (b);    //原來這樣。。

int m = ((a++) < (b) ? (a++) : (b));    //原來這樣。。

int d = sizeof(c)/sizeof(*c);

return 0;

}

經過預處理巨集展開後,我們看到s2與m變數的值,現在相信你已經能理解了,這也是巨集表示式比函式更容易出錯。

巨集表示式與函式的對比

-巨集表示式被預處理器處理,編譯器不知道巨集表示式的存在

-巨集表示式用 "實參" 完全替代形參,不進行任何運算

-巨集表示式沒有任何"呼叫"開銷

-巨集表示式不能出現遞迴定義

思考:巨集表示式是否存在作用域限制問題?下邊的**是否能正常編譯?

#include void def()

double area(double r)

int main()

我們來編譯執行一下:

很明顯,能編譯執行,我們在單獨用預處理器處理下(這裡把頭檔案與列印語句注釋掉,因為預處理後會展開很多東西),看看中間檔案,

#line 1 "21-3.c"

void def()

double area(double r)

int main()

從中間檔案,可以看出,編譯器根本不知道#define巨集常量的存在,所以#define巨集也就沒有什麼作用域限制。這也符合文章開頭我們所說的:#define定義之後的**都可以使用這個巨集來看看c語言中幾個強大的內建巨集

下半邊以乙個綜合示例來展示下#define巨集的魅力:

#include #include #define malloc(type, x) (type*)malloc(sizeof(type)*x)

#define free(p) (free(p), p=null)

#define log(s) printf("[%s] %s \n", __date__, __file__, __line__, s)

#define foreach(i, m) for(i=0; i執行結果:

總結:1、預處理器直接對巨集進行文字替換

2、巨集使用時的引數不會進行求值和運算

3、預處理器不會對巨集定義進行語法檢查

4、巨集定義時出現的語法錯誤只能被編譯器檢測

5、巨集定義的效率高於函式呼叫

6、巨集的使用會帶來一定的***

簡單講解C語言中巨集的定義與使用

巨集定義是預編譯功能的一種,預編譯又稱為預處理,是為編譯做的預備工作的階段。處理 開頭的指令,比如拷貝 程式設計客棧 include 包含的檔案 define巨集定義的替換,條件編譯等。使用巨集定義的好處 使用巨集定義的好處 可提高程式的通用性和易讀性,減少不一致性,減少輸入錯誤和便於修改。例如 這...

c 語言中的巨集定義

巨集定義 巨集定義是c提供的三種預處理功能的其中一種,這三種預處理包括 巨集定義 檔案包含 條件編譯 1.不帶引數的巨集定義 巨集定義又稱為巨集代換 巨集替換,簡稱 巨集 格式 define 識別符號 字串 其中的識別符號就是所謂的 符號常量,也稱為 巨集名 預處理 預編譯 工作也叫做巨集展開 將巨...

C語言中的巨集定義

下列c 中包含兩種巨集定義,例如 include define max connection 1000 define mng port 5000 define min a,b a b a b define max a,b a b a b int main 方法1 gcc e 引數預編譯 gcc e ...