ios開發系列--c語言之預處理
大家都知道乙個c程式的執行包括編譯和鏈結兩個階段,其實在編譯之前預處理器首先要進行預處理操作,將處理完產生的乙個新的原始檔進行編譯。由於預處理指令是在編譯之前就進行了,因此很多時候它要比在程式執行時進行操作效率高。在c語言中包括三類預處理指令,今天將一一介紹:
巨集定義條件編譯
檔案包含
對於程式中經常用到的一些常量或者簡短的函式我們通常使用巨集定義來處理,這樣做的好處是對於程式中所有的配置我們可以統一在巨集定義中進行管理,而且由於巨集定義是在程式編譯之前進行替換相比定義成全域性變數或函式效率更高。
#include
#define
pi 3.14
//巨集定義一般大寫
#define
r 10
#define
s 2*pi*r
//在另乙個巨集裡面引用了上面的巨集
int
main(
int
argc,
const char
* argv)
巨集定義實際的操作就是在預處理時進行對應替換,這個階段不管語法是否正確,而且對於字串中出現的巨集名不會進行替換。巨集定義的功能事實上是非常強大的,除了簡單的常量替換還可以傳入引數:
#include
#define
sum(a,b) a+b
#define
sub(a,b) (a-b)
#define
mul (a,b) (a*b)
//這麼定義是錯誤的,預處理器會認為巨集名為」mul「,替換內容為」(a,b) (a*b)「
int
main(
int
argc,
const char
* argv)
上面我們可以看出帶引數的巨集功能很強大,有點類似於函式,同函式不同的是它只是簡單的替換,不涉及儲存空間分配,引數、返回值等問題,但是由於它在預處理階段展開,所以一般效率較高。使用帶引數的巨集需要注意的就是結果最好用括號括起來否則很容易出現問題(在上面的sum例子中我們應該已經看到了);還有一點就是帶引數的巨集定義時名稱和引數之間不要有空格。
條件編譯其實就是在編譯之前預處理器根據預處理指令判斷對應的條件,如果條件滿足就將對應的**編譯進去,否則**就根本不進入編譯環節(相當於根本就沒有這段**)。
#include
#define
count 1
int
main(
int
argc,
const char
* argv)
檔案包含指令#include在前面也多次使用過,這裡再次強調一下。首先使用#include「***」包含和使用#include 包含的不同之處就是使用<>包含時,預處理器會搜尋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」雖然沒有報錯,但這會影響編譯的效能,正確的做法應該是這樣的:
其實就是用巨集定義判斷乙個巨集是否定義了,如果沒有定義則會定義這個巨集,這樣以來如果已經包含過則這個巨集定義肯定已經定義過了,即使再包含也不會重新定義了,下面的**也就不會包含進去。
ios開發系列--c語言之預處理
iOS開發系列 C語言之預處理
大家都知道乙個c程式的執行包括編譯和鏈結兩個階段,其實在編譯之前預處理器首先要進行預處理操作,將處理完產生的乙個新的原始檔進行編譯。由於預處理指令是在編譯之前就進行了,因此很多時候它要比在程式執行時進行操作效率高。在c語言中包括三類預處理指令,今天將一一介紹 巨集定義條件編譯 檔案包含 對於程式中經...
iOS開發之 C語言之預處理
大家都知道乙個c程式的執行包括編譯和鏈結兩個階段,其實在編譯之前預處理器首先要進行預處理操作,將處理完產生的乙個新的原始檔進行編譯。由於預處理指令是在編譯之前就進行了,因此很多時候它要比在程式執行時進行操作效率高。在c語言中包括三類預處理指令,今天將一一介紹 巨集定義條件編譯 檔案包含 對於程式中經...
C語言之預處理
預處理指令 在 編譯 0和1 之前執行的指令叫預處理指令。所有的預處理指令都是以 開頭。預處理的位置是隨便寫的 預處理指令的作用域 從編寫指令的那一行開始一直到檔案結尾 undef 巨集名 從這行 開始,巨集失效 巨集名一般用大寫 或者在巨集名前加 k 代表常量 變數名一般用小寫 一 巨集定義 格式...