**:
巨集定義語法
#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...