預處理是c編譯器做的第一件事情,主要是做一些文字方面的工作。包括:刪除注釋、插入被#include包含的檔案、定義和替換由#define指令定義的符號以及**的部份內容,和條件編譯。
預定義符號
預定義符號如下表所示:
__file__
進行編譯的檔名
__line__
檔案的當前行號
__date__
檔案編譯的日期
__time__
檔案編譯的時間
__stdc__
如果遵循ansi c,它被定義
預定義符號都是雙下劃線,通常用到最多的是前2個,用於列印log.
#define
此指令應該是最為常見的,它的一般描述是
#define name stuff
stuff是可選的。stuff不僅可以是常量,任何文字都可以用於替換。
#define name(parameter-list) stuff
上面這種形式被稱為巨集macro,它作為函式的替換的方式之一被廣泛採用。不過c++中不太推薦這種方法,轉而使用模板。不過,巨集函式還是有很特殊的地方,且模版亦不能代替。比如字串代替。
#define print(format, value) \
printf("the value is "format" ", value)
在巨集引數兩邊加上引號,表示以字串形式替換。例如,下面的語句:
print("%d", x+10);
經過預編譯後變為
printf("the value is %d", x+10);
這種轉換只有當巨集引數是字串常量時,才可以被處理。如果在stuff裡巨集引數前加上'#',則對任意文字都有效。比如下面
#define print(format, value) \
printf("the value is "#value" = "format" ", value)
那麼上面那條語句會編譯為
printf("the value is x+10 = %d", x+10);
這樣大提高了巨集引數的靈活性。甚至,預處理器還有連線功能'##'。
#define add(n, value) hd##n += value …
add(a, 3); óhad += 3;
在許多的高階程式中,這類「奇技淫巧」被廣泛使用。一方面,巨集替換比函式往往能獲得更高的效率;更重要的是,這類字串處理是c/c++這種非指令碼語言無法實現的。
#undef
通常是重定義乙個巨集。因為如果乙個巨集已經定義了,那麼必須先取消定義,才能重新定義。
命令列定義
命令列定義就是通過編譯器來定義。各種編譯器都提供了乙個選項來定義巨集。以gcc為例:
gcc -dmax_size=100 -dlittle_endian
這裡定義了兩個,max_size為100,little_endian沒有指定值,那麼預設為0.
命令列也可以取消定義,用-u。方法就不敘述了。(注意:gcc和cl都是區分大小寫的)
條件編譯
具體地講,條件編譯就是幾個條件指令:#if, #ifdef, #elseif, #else, #endif, #ifundef, defined。比如,判斷乙個巨集是否定義,有三種方式:
1. #if macro_
2. #ifdef macro_
3. #if defined(macro_)
一般情況下,用前兩個就可以了。但是後乙個也非常有用,比如要判斷多個條件組合時
#if defined(!macro1 || macro2 && macro3 )
用其它方式會很麻煩。
其它指令
#error text-to-print
讓編譯器輸出資訊對開發者來說,比注釋更有效。
C預處理器簡介
cpreprocesser,簡稱cpp,是c編譯器在編譯原始碼之前用於轉換 的巨集處理器。之所以稱之為巨集處理器,是因為通過cpp,你可以在程式中定義和使用巨集。cpp是一種文字處理工具,因此也可以用於c c 和objective c之外的原始碼。cpp的作用是對輸入的檔案做一系列的文字處理,這些文...
預處理器小結
預處理器發生在程式被編譯之前,所有的預處理器指令都以 開頭。1.include預處理器指令 使指定檔案的乙個副本被包含到指令所在的位置。include 與 include filename 區別 簡單不加以說明 include 指令用於包含標準類庫標頭檔案,也可以用於由多個原始檔組成的程式。2.in...
C 預處理器
偶爾翻c 的教材,看到了一些以前自己不太關注的角落。參考教材 c 大學教程 harvey m.deitel 和paul james deitel著。預處理發生在編譯之前,包括把其他檔案包含到要編譯的檔案中 定義符號常量和巨集 程式 的條件編譯以及預處理指令的條件執行。對應的,預處理指令有 檔案包含命...