C/C++編程筆記:C語言預(yù)編譯指令—條件編譯,零基礎(chǔ)推薦收藏
一、 內(nèi)容概述
本文主要介紹c語言中條件編譯相關(guān)的預(yù)編譯指令,包括#define、#undef、#ifdef、#ifndef、#if、#elif、#else、#endif、defined。

二、條件編譯
條件編譯是根據(jù)實(shí)際定義宏(某類條件)進(jìn)行代碼靜態(tài)編譯的手段??筛鶕?jù)表達(dá)式的值或某個特定宏是否被定義來確定編譯條件。
最常見的條件編譯是防止重復(fù)包含頭文件的宏,形式跟下面代碼類似:

在實(shí)現(xiàn)文件中通常有如下類似的定義:

這些都是條件編譯的常用情境。
三、條件編譯中使用的預(yù)編譯指令
#define? ? ? ? ? ?定義一個預(yù)處理宏
#undef ? ? ? ? ? ?取消宏的定義
#if ? ? ? ? ? ? ? ? ? 編譯預(yù)處理中的條件命令,相當(dāng)于C語法中的if語句
#ifdef ? ? ? ? ? ? ?判斷某個宏是否被定義,若已定義,執(zhí)行隨后的語句
#ifndef ? ? ? ? ? ?與#ifdef相反,判斷某個宏是否未被定義
#elif ? ? ? ? ? ? ? ?若#if, #ifdef, #ifndef或前面的#elif條件不滿足,則執(zhí)行#elif之后的語句,相當(dāng)于C語法中的else-if
#else ? ? ? ? ? ? ?與#if, #ifdef, #ifndef對應(yīng), 若這些條件不滿足,則執(zhí)行#else之后的語句,相當(dāng)于C語法中的else
#endif ? ? ? ? ? ? #if, #ifdef, #ifndef這些條件命令的結(jié)束標(biāo)志.
defined? ? ? ? ? ?與#if, #elif配合使用,判斷某個宏是否被定義
四、預(yù)編譯指令應(yīng)用舉例
1. #define、#undef
#define命令定義一個宏:
#define MACRO_NAME[(args)] [tokens[(opt)]]
之后出現(xiàn)的MACRO_NAME將被替代為所定義的標(biāo)記(tokens)。宏可帶參數(shù),而后面的標(biāo)記也是可選的。
宏定義,按照是否帶參數(shù)通常分為對象宏、函數(shù)宏兩種。
對象宏:?不帶參數(shù)的宏被稱為"對象宏(objectlike macro)"。對象宏多用于定義常量、通用標(biāo)識。例如:

函數(shù)宏:帶參數(shù)的宏。利用宏可以提高代碼的運(yùn)行效率: 子程序的調(diào)用需要壓棧出棧, 這一過程如果過于頻繁會耗費(fèi)掉大量的CPU運(yùn)算資源。
所以一些代碼量小但運(yùn)行頻繁的代碼如果采用帶參數(shù)宏來實(shí)現(xiàn)會提高代碼的運(yùn)行效率。但多數(shù)c++程序不推薦使用函數(shù)宏,調(diào)試上有一定難度,可考慮使用c++的inline代替之。例如:

#undef可以取消宏定義,與#define對應(yīng)。
2. defined
defined用來測試某個宏是否被定義。defined(name): 若宏被定義,則返回1,否則返回0。
它與#if、#elif、#else結(jié)合使用來判斷宏是否被定義,乍一看好像它顯得多余, 因?yàn)橐呀?jīng)有了#ifdef和#ifndef。defined可用于在一條判斷語句中聲明多個判別條件;#ifdef和#ifndef則僅支持判斷一個宏是否定義。

和#if、#elif、#else不同,#ifdef、#ifndef、defined測試的宏可以是對象宏,也可以是函數(shù)宏。
3. #ifdef、#ifndef、#else、#endif
條件編譯中相對常用的預(yù)編譯指令。模式如下:

#ifdef用于判斷某個宏是否定義,和#ifndef功能正好相反,二者僅支持判斷單個宏是否已經(jīng)定義,上面例子中二者可以互換。如果不需要多條件預(yù)編譯的話,上面例子中的#elif和#else均可以不寫。
4.?#if、#elif、#else、#endif
#if可支持同時判斷多個宏的存在,與常量表達(dá)式配合使用。常用格式如下:

常量表達(dá)式可以是包含宏、算術(shù)運(yùn)算、邏輯運(yùn)算等等的合法C常量表達(dá)式,如果常量表達(dá)式為一個未定義的宏, 那么它的值被視為0。

在判斷某個宏是否被定義時,應(yīng)當(dāng)避免使用#if,因?yàn)樵摵甑闹悼赡芫褪潜欢x為0。而應(yīng)當(dāng)使用#ifdef或#ifndef。
注意: #if、#elif之后的宏只能是對象宏。如果宏未定義,或者該宏是函數(shù)宏,則編譯器可能會有對應(yīng)宏未定義的警告。
五、總結(jié)
本文主要介紹c語言中有關(guān)預(yù)編譯的指令。撰寫本文的目的在于理清相關(guān)概念調(diào)用,在后續(xù)預(yù)編譯使用時可以找到最合適的指令及格式。比如同時滿足多個宏定義的預(yù)編譯、多分支預(yù)編譯、#elif和#else指令的配合等。

學(xué)習(xí)C/C++編程知識,提升C/C++編程能力,歡迎關(guān)注UP一起來成長!
另外,UP在主頁上傳了一些學(xué)習(xí)C/C++編程的視頻教程,有興趣或者正在學(xué)習(xí)的小伙伴一定要去看一看哦!會對你有幫助的~