【C语言进阶深度学习记录】十八 条件编译的使用与分析
文章目錄
- 1 基本概念
- 1.1 代碼分析
- 1.2 通過(guò)命令行定義宏
- 2 #include 的本質(zhì)
- 2.1 解決重復(fù)包含頭文件的問(wèn)題
- 3 條件編譯的應(yīng)用
- 4 總結(jié)
1 基本概念
- 條件編譯的行為類似于C語(yǔ)言中的if … else…
- 條件編譯是預(yù)編譯指示指令,用于控制是否編譯某段代碼
比如下圖的代碼:
- 上面的 #if、#else、#endif 就是條件編譯的構(gòu)成當(dāng)然,還有其他的樣式,后面會(huì)通過(guò)例子詳細(xì)說(shuō)明。
1.1 代碼分析
如下代碼:
- 22-1.c
- 上述代碼編譯運(yùn)行結(jié)果為:
This is first printf…
上面的代碼,看起來(lái)很簡(jiǎn)單,實(shí)際上,因?yàn)闂l件編譯雖然像if…else 但是它并不像if…else那樣在程序運(yùn)行的時(shí)候進(jìn)行判斷,而是在預(yù)編譯器編譯的時(shí)候就決定了。什么意思呢?可以使用預(yù)編譯指令對(duì)上述代碼進(jìn)行預(yù)編譯(當(dāng)然,為了簡(jiǎn)潔,先將1行和第14行需要使用標(biāo)準(zhǔn)庫(kù)文件的代碼注釋掉)
- gcc -E 22-1.c -o 22-1.i
- 生成的預(yù)編譯文件22-1.i 內(nèi)容如下:
- 可以看到,在預(yù)編譯階段,就已經(jīng)將條件編譯指令處理完了,預(yù)編譯結(jié)束后,就只剩下,條件編譯中為真的那段代碼。如上面的代碼。所以我們可以總結(jié)出下面幾條規(guī)則:
1.2 通過(guò)命令行定義宏
- 補(bǔ)充一點(diǎn),我們還可以通過(guò)命令行定義宏,而無(wú)需再代碼中定義,如下圖所示:
如下代碼:
- 22-2.c
- gcc 22-2.c -o 22-2.out
運(yùn)行結(jié)果為:
This is second printf…
- gcc -DC 22-2.c -o 22-2.out 或者 gcc -DC=1 22-2.c -o 22-2.out
運(yùn)行結(jié)果為:
This is first printf…
我想上面的示例,已經(jīng)足以讓我們學(xué)會(huì)使用命令行定義宏了
2 #include 的本質(zhì)
這個(gè)我們已經(jīng)熟悉的不能再熟悉的東西了,包含頭文件,有什么玄機(jī)?
- #include 的本質(zhì)是將已經(jīng)存在的文件嵌入到當(dāng)前文件中
- #include 的間接包含,同樣會(huì)產(chǎn)生嵌入文件的操作,這樣會(huì)導(dǎo)致一個(gè)文件包含兩個(gè)相同的頭文件,這會(huì)產(chǎn)生錯(cuò)誤。
比如下圖的形式,編譯會(huì)出錯(cuò):
以下面三個(gè)代碼為例,來(lái)說(shuō)明:
- global.h代碼
- test.h
- 2-3.c
編譯運(yùn)行上述三個(gè)代碼;
- gcc 22-3.c -o 22-3.out
- ./22-3.out
上面錯(cuò)誤的行數(shù)不一樣是因?yàn)槲覀€(gè)人的代碼行數(shù)與上面的不一樣,這個(gè)可以忽略
- 從上面的錯(cuò)誤可以看出,變量global 重復(fù)定義了。很明顯,我們并沒(méi)有重復(fù)定義。
- 對(duì)上述代碼進(jìn)行預(yù)編譯(首先將第1、10、11 行注釋掉,方便文件內(nèi)容查看),gcc -E 22-3.c -o 22-3.i 得出的預(yù)編譯文件內(nèi)容如下:
從上面的預(yù)編譯文件可以看出:
2.1 解決重復(fù)包含頭文件的問(wèn)題
在一個(gè)大型軟件中,重復(fù)包含頭文件是非常普遍的,如果我們一個(gè)一個(gè)的去找,那就會(huì)太浪費(fèi)時(shí)間。
使用條件編譯,是可以解決該問(wèn)題的。比如將上面的global.h 與test.h改為如下樣式:
- global.h
- test.h
改好上面兩個(gè)文件后,重新編譯運(yùn)行代碼,結(jié)果如下:
- 上面改變后的global.h與test.h 只是加了個(gè)條件編譯指令,如果某一頭文件被包含過(guò)一次,再要包含它的時(shí)候,由于不符合條件編譯的條件,就不會(huì)有后面的代碼,這樣就避免了一個(gè)頭文件被重復(fù)包含的錯(cuò)誤。(如果不理解,回頭從頭看起,多看兩遍)
3 條件編譯的應(yīng)用
條件編譯可以定義軟件產(chǎn)品的發(fā)布版與調(diào)試版 。
可以在代碼中使用條件編譯來(lái)定義需要調(diào)試的代碼,當(dāng)整個(gè)軟件產(chǎn)品都調(diào)試通過(guò)最終需要發(fā)布的時(shí)候,可以直接去掉相關(guān)的宏定義(或者直接使用命令行的時(shí)候,不定義調(diào)試需要的宏即可),就可以使得代碼在編譯的時(shí)候,直接刪除調(diào)試部分的代碼,而無(wú)需自己動(dòng)手刪除。
本部分就不寫(xiě)實(shí)驗(yàn)了。
4 總結(jié)
- 條件編譯可以使得我們按照不同的條件編譯不同的代碼片段,因而可以產(chǎn)生不同的目標(biāo)代碼
- 通過(guò)編譯器命令行,可以定義預(yù)處理器使用的宏
- 條件編譯,可以避免重復(fù)包含同一個(gè)頭文件多次
- 條件編譯可以定義軟件產(chǎn)品的發(fā)布版和調(diào)試版
總結(jié)
以上是生活随笔為你收集整理的【C语言进阶深度学习记录】十八 条件编译的使用与分析的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 零碎的小知识点 ----------C#
- 下一篇: 【C语言进阶深度学习记录】二十三 数组