大家都知道一個c程式的運作包括編譯和連結兩個階段,其實在編譯之前預處理器首先要進行預處理操作,将處理完産生的一個新的源檔案進行編譯。由于預處理指令是在編譯之前就進行了,是以很多時候它要比在程式運作時進行操作效率高。在c語言中包括三類預處理指令,今天将一一介紹:
<a href="http://www.cnblogs.com/kenshincui/p/3854242.html#macro">宏定義</a>
<a href="http://www.cnblogs.com/kenshincui/p/3854242.html#conditional">條件編譯</a>
<a href="http://www.cnblogs.com/kenshincui/p/3854242.html#include">檔案包含</a>
對于程式中經常用到的一些常量或者簡短的函數我們通常使用宏定義來處理,這樣做的好處是對于程式中所有的配置我們可以統一在宏定義中進行管理,而且由于宏定義是在程式編譯之前進行替換相比定義成全局變量或函數效率更高。
宏定義實際的操作就是在預處理時進行對應替換,這個階段不管文法是否正确,而且對于字元串中出現的宏名不會進行替換。宏定義的功能事實上是非常強大的,除了簡單的常量替換還可以傳入參數:
上面我們可以看出帶參數的宏功能很強大,有點類似于函數,同函數不同的是它隻是簡單的替換,不涉及存儲空間配置設定,參數、傳回值等問題,但是由于它在預處理階段展開,是以一般效率較高。使用帶參數的宏需要注意的就是結果最好用括号括起來否則很容易出現問題(在上面的sum例子中我們應該已經看到了);還有一點就是帶參數的宏定義時名稱和參數之間不要有空格。
條件編譯其實就是在編譯之前預處理器根據預處理指令判斷對應的條件,如果條件滿足就将對應的代碼編譯進去,否則代碼就根本不進入編譯環節(相當于根本就沒有這段代碼)。
檔案包含指令#include在前面也多次使用過,這裡再次強調一下。首先使用#include“xxx”包含和使用#include <xxx>包含的不同之處就是使用<>包含時,預處理器會搜尋c函數庫頭檔案路徑下的檔案,而使用“”包含時首先搜尋程式所在目錄,其次搜尋系統path定義目錄,如果還是找不到才會搜尋c函數庫頭檔案所在目錄。
另外在使用#include的時候我們需要注意包含檔案的時候是不能遞歸包含的,例如a.h檔案包含b.h,而b.h就不能再包含a.h了;還有就是重複包含雖然是允許的(這裡指的是重複包含頭檔案)但是這會降低編譯性能,不妨看一下下面的例子:

上面有三段代碼,在main.c和person.h中都包含了message.h而main.c自身又包含了person.h,這樣程式在預處理階段會對包含内容進行替換,替換後mian.c中包含了兩個#include “message.h”雖然沒有報錯,但這會影響編譯的性能,正确的做法應該是這樣的:
其實就是用宏定義判斷一個宏是否定義了,如果沒有定義則會定義這個宏,這樣以來如果已經包含過則這個宏定義肯定已經定義過了,即使再包含也不會重新定義了,下面的代碼也就不會包含進去。