在c語言中以#開頭的語句都叫做預處理指令,因為這些不是標準的c**,不能被編譯器直接編譯,需要一段程式把它翻譯成標準的c**,負責翻譯的程式叫預處理器,翻譯的過程叫預處理。
gcc -e code.c
把預處理的結果顯示在終端上
gcc -e code.c -o code.i
把預處理的結果儲存到檔案中(-o :重新命名,為執行/編譯的結果重新取名)
例:gcc hello.c -o hello -> 原本 hello.c -o 出來 a.out,現在叫 hello
#include < >
從系統指定的路徑載入標頭檔案
#include " "
先從當前路徑載入標頭檔案,如果沒有再從系統指定的路徑載入標頭檔案
系統指定路徑:
1、作業系統通過設定環境變數來指定載入標頭檔案的路徑
2、-i 路徑:編譯時指定載入標頭檔案的路徑
gcc test.c -i. // . :表示當前目錄
gcc test.c -i/home/text/ // 寫出具體路徑也可以
防止標頭檔案被重複包含
#ifndef file_h
注意:在標準庫裡面:# ifndef _ stdio _ h【檔名前有小橫槓( _ )】,自己寫的不加( _ ),要以示區別
ifndef 用來判斷是否有定義此檔名,沒有則為真
# define file_h
…#endif // file_h
標頭檔案衛士作用簡析:
若有 a.h、b.h、c.h
其中 b.h 包含 a.h
且 c.h 包含 a.h 再包含 b.h
這樣a.h 在 c.h 裡面變成有兩份,而標頭檔案衛士可以解決這種問題
注意:
標頭檔案衛士不能解決迴圈包含的問題
a.h 包含 b.h, 而b.h 包含 a.h
則 a.h,b.h 裡引數和函式都需要互相呼叫,導致編譯器不知道要先呼叫a還是先呼叫b
因此會出現隱式宣告
解決辦法:
把a.h 和 b.h 共用的記憶體提出來再寫乙個 c.h ,然後 a.h 和 b.h 都包含 c.h
單純巨集 #define name
可以配合標頭檔案衛士,條件編譯使用
巨集常量 #define pi 3.14
預處理器會把**中的所有巨集名替換成它後面的數字
好處:
1、比用變數安全性高
2、比直接使用資料的擴充套件性強
3、可以為資料取乙個有意義的名字,提高可讀性
注意:定義巨集時不能帶分號,一般巨集名都全部大寫
帶引數的巨集,並不是真正的函式,只是使用樣式與函式一樣
其實就是把乙個複雜的公式抽象成乙個像函式一樣的巨集
如果巨集函式的內容太長,可以使用大括號,但是不能換行(可以使用續行符 \ )
#define sum(a,b) a+b
#define swap(x,y) \
else\
\}
優點:
1、方便使用
2、速度快(因為沒有進行引數傳遞、壓棧、出棧、釋放棧的過程)
缺點:
1、不會對引數進行型別檢查(只是簡單的替換),安全性差
2、沒有返回值,只有乙個運算結果,因此處理不了很複雜的業務邏輯
3、過多使用會增加**段的冗餘(每次呼叫,**段就會增加一段,不像函式只有一段)
注意:
1、二義性(環境不同運算規則不同)
-> 給每乙個引數都加上( )可以盡可能地避免二義性
2、呼叫巨集函式時不要使用自變運算子(自變運算子會在巨集裡面加減多次)
預處理指令
預處理指令是我們寫在程式 中的給預處理器 preprocessor 的 命令,而不是程式本身的語句。預處理器在我們編譯乙個c 程式時由編譯器自動執行,它負責控制對程式 的第一次驗證和消化。所有這些指令必須寫在單獨的一行中,它們不需要加結尾的分號 在這個教程的開頭我們已經提到了一種預處理指令 defi...
預處理指令
1.人們常常稱機器語言為目標 object code 2.預處理命令 preprocessor directives 三種預處理包括 巨集定義 檔案包含 條件編譯。在對源程式編譯之前,會對程式中的所有預處理指令進行處理。預處理就是在進行編譯的第一遍詞法掃瞄和語法分析之前所作的工作。說白了,就是對原始...
預處理指令
普通 define 巨集名 字串 define my int int define max 10000 帶引數 define 巨集名 形參 字串 define add x,y x y 在大規模的開發過程中,特別是跨平台和系統的軟體裡,條件編譯很重要。include using namespace s...