c 巨集定義用法 define

2021-09-22 14:10:32 字數 3089 閱讀 8769

**:

巨集定義語法

#define name stuff

#define pi 3.14

//定義乙個m,值為3.14

#define do_forever for(;;)

//定義乙個死迴圈

#define reg register

//定義reg來作為register的別名

#define case break;case

//在switch中用case來補上break;

#define debug_print printf("file:%s\tline:%d\tdate:%s\ttime:%s\n",\

__file__, __line__, __date__, __time__);

//測試預定義符號12

3456

78910

111、巨集的作用範圍

先看下面**:

1. 在呼叫巨集時,首先對引數進行檢查,看看是否包含任何由#define定義的符號。如果是,它們首先被替換。

2. 替換文字隨後被插入到程式中原來文字的位置。對於巨集,引數名被他們的值替換。

3. 最後,再次對結果檔案進行掃瞄,看看它是否包含任何由#define定義的符號。如果是,就重複上述處理過程。

注意:1、巨集函式不能出現遞迴

2、巨集定義的符號,即name部分不會在預處理替換的時候被搜尋

3、巨集定義#define後不需要加;

例如:#define m 100;

這裡在100後面加上了;

在句子中有時候就會出現問題

觀察下面**片段:

#define m 100;

if (condition)

m = m;

else

max = 0;12

345在該選擇語句中會出現語法錯誤,沒有與else與之匹配的if語句

4、巨集函式申明

巨集函式申明格式:

#define name ( parament-list ) stuff

parament-list為參數列,可以包含多個引數,他們會在stuff出現

例如:#define sqare( x ) x*x

//定義乙個計算乘方的巨集函式12

但是這麼定義是會出現預料之外的錯誤的,觀察下面**片段

#define square(x) x*x

int main()12

3456

78本來結果應該為6^2 = 36

#define double(x) (x) + (x)

int main()12

3456

78期望結果為100,而看程式執行結果:

在c語言中

printf(「hello」」 world!」「\n」);

這句話是合法的

列印結果為:

hello world!

按照上述原則,我們可以寫出下列**:

#define print(format, value) printf("the value of " #value " is "format"\n", value)

int main()12

3456

78看下gcc編譯後的**,程式正常執行:

#value被替換成了「i + 3」

別忘了被替換的時候i + 3兩邊加上了雙引號

##的用法

看下面的**片段

#define add_to_an(num, value) a##num += value

int main()12

3456

78910

解釋一下上面這段**

假設有乙個變數叫a1

此時**片段為add_to_an(1, 5)

即替換為a1 += 5,給a1變數增加5

同理add_to_an(2, 6)則替換成a2 += 6

##的作用

將##兩邊的字元連在一起作為乙個識別符號

前提連線後的識別符號必須合法,否則編譯出現識別符號未定義

6、巨集和函式

巨集通常被應用於執行簡單的運算

和函式相比,巨集有他的優點

巨集的優點:

1. 用於呼叫函式和從函式返回的**可能比實際執行這個小型計算工作所需要的時間更多。所以巨集比函式在程式的規模和速度方面更勝一籌

2. 更為重要的是函式的引數必須宣告為特定的型別。所以函式只能在型別合適的表示式上使用。反之這個巨集怎可以適用於整形、長整型、浮點型等可以用於》來比較的型別。巨集的引數與型別無關的

3. 巨集引數可以使用變數型別,而函式不可以,例如:

#define malloc(num, type) (type *)malloc(num * sizeof(type))

malloc(10, int);//型別作為引數

//預處理器替換之後:

(int *)malloc(10 * sizeof(int));12

345但是,巨集引數與型別無關是一把雙刃劍,和函式比較也有他的缺點

巨集的缺點:

1. 每次使用巨集的時候,乙份巨集定義的**將插入到程式中。除非巨集比較短,否則可能大幅度增加程式的長度

2. 巨集是沒法除錯的

3. 巨集由於型別無關,也就不夠嚴謹

4. 巨集可能會帶來運算子優先順序的問題,導致程式容易出現問題

我的建議:

當有一部分功能既可以用函式實現也可以用巨集實現,且在呼叫函式的過程與巨集使用過程所消耗的資源相當時,優先考慮**的嚴謹性,使用函式

7、巨集引數的***

當巨集引數在巨集的定義**現超過一次的時候,如果引數帶有***,那麼你在使用這個巨集的時候就可能出現危險,導致不可**的後果。***就是表示式求值的時候出現的永久性效果。

#define max(a, b) ( (a) > (b) ? (a) : (b) )

x = 5;

y = 8;

z = max(x++, y++);

printf("x=%d y=%d z=%d\n", x, y, z);

//結果為x=6 y=10 z=912

3456

7可以看到上面**中y++帶來了***,所以在使用巨集的時候,避免使用++運算和--運算

8、巨集的命名

巨集和函式的使用很類似,我們平時的使用習慣是:

C語言 巨集定義 define的用法

這種用法是最簡單最常見的一種方式,如下 define pai 3.14注意 它的功能是在程式中若出現了pai,就把它替換為3.14,示例程式如下 include define pai 3.14 不帶參巨集定義 intmain 使用方法如下 define add a,b a b 它的功能是計算a b的...

C 巨集定義 define

可以用 define命令將乙個指定的識別符號 即巨集名 來代表乙個字串。定義巨集的作用一般是用乙個短的名字代表乙個長的字串。它的一般形式為 define 識別符號 字串 這就是已經介紹過的定義符號常量。如 define pi 3.1415926 還可以用 define命令定義帶引數的巨集定義。其定義...

c語言巨集定義 define

數值巨集常量 define 巨集定義可以定義在 的任何地方,從本行巨集定義開始到後面 都認識這個巨集 可以把任何東西定義成巨集。因為編譯器在預編譯的時候用真身替換替身,然而在 裡面卻又常用替身來幫忙。巨集定義是個演技高超的替身演員,但也會經常耍大牌的,我們慎用它。define pi 3.141592...