C語言學習筆記_C語言巨集定義與預處理
阿新 • • 發佈:2020-07-14
C語言學習筆記_C語言巨集定義與預處理
由原始碼到可執行程式的過程
- 原始碼;
- 預處理過的.i原始檔
- 彙編檔案.s
- 目標檔案.o
- elf可執行程式
條件編譯
// 定義XXX
#define XXX
// 這種方式直接判定XXX是否被定義
#ifdef XXX
#else
#endif
// 這種方式判斷條件是否為真
#if (1)
#else
#endif
巨集定義
巨集定義在編譯器的預處理階段會被直接替換;
替換的過程是遞迴的,如下:
#define N 10
#define M N
// 相當於int a[10];
int a[M];
當巨集定義帶引數的時候,擅用括號,避免替換的時候出現歧義,如獲取最大值的巨集:
#define MAX(a, b) ((a) > (b) ? (a) : (b))
int max(int a, int b) {
return a>b?a:b;
}
int a = 1, b = 2;
int max = MAX(a*3, b);
這裡例子可能舉得不是很好,但是在某些時候不加括號會使得替換後引起歧義,導致出錯;
帶參巨集和帶參函式有如下差別:
- 巨集定義原地展開,因此沒有呼叫開銷;而函式是跳轉執行在返回;
- 巨集定義不會檢查引數的型別,返回值也不會附帶型別,而函式有明確的引數型別和返回值型別;當呼叫函式時編譯器會做引數的靜態型別檢查;
另外一個例子,利用巨集定義得到一年有多少秒:
#define SER_PER_YEAR (365*24*60*60UL)
注意:
在程式中的數字預設為int型別,而秒數正好超過了int的範圍;
所以在數字後面加上UL使得陣列變成無符號long;
另外一個例子,利用條件巨集設定debug
// 定義DEBUG
#define DEBUG
// 使用undef消除對DEBUG的定義
#undef DEBUG
#ifdef DEBUG
#define debug(x) printf(x)
#else
#define debug(x)
#endif
debug("hello world.\n");
通過定義DEBUG,使得debug可以用於列印資訊,如果不需要了可以註釋DEBUG的定義,或者使用undef,使得消除除錯資訊更方便。
使用undef時,前面若沒有定義過,將會無視此語句;
行內函數
在巨集定義中講到,帶參巨集和函式的區別是:帶參巨集開銷小但是不做型別檢查,函式有呼叫開銷但是會做型別檢查;
而內斂函式具有上述兩者的優點,其沒有呼叫開銷且會做型別檢查,只需要在函式前加inline
inline void printInfo() {
printf("hello world.\n");
}