一般情況下,在進行編譯時對源程式中的每一行都要編譯。但是有時希望程式中某一部分內容只在滿足一定條件時才進行編譯,也就是指定對程式中的一部分內容進行編譯的條件。如果不滿足這個條件,就不編譯這部分內容。這就是「條件編譯」。 其實這跟事物具有多樣性一樣。我們需要對不同的狀況下採取不同的操作。例如程式的執行平台具有這種多樣性,我們在window平台下編寫的程式,可能使用某乙個庫或者與硬體相關的屬性、方法。現在要將我們的程式移植到別的計算機系統的時候,例如linux系統。那麼程式上依賴的庫或者有些和硬體相關聯的屬性和方法不得不更改,那麼我們只能在編寫程式的時候提高程式的健壯性,此時就需要條件編譯語句為我們實現這樣的功能。
常見的預編譯和條件編譯指令:
#define 定義乙個預處理巨集
#undef 取消巨集的定義
#if 編譯預處理中的條件命令,相當於c語法中的if語句
#ifdef 判斷某個巨集是否被定義,若已定義,執行隨後的語句
#ifndef 與#ifdef相反,判斷某個巨集是否未被定義
#elif 若#if, #ifdef, #ifndef或前面的#elif條件不滿足,則執行#elif之後的語句,相當於c語法中的else-if
#else 與#if, #ifdef, #ifndef對應, 若這些條件不滿足,則執行#else之後的語句,相當於c語法中的else
#endif #if, #ifdef, #ifndef這些條件命令的結束標誌.
defined 與#if, #elif配合使用,判斷某個巨集是否被定義
有時,希望當滿足某條件時對一組語句進行編譯,而當條件不滿足時則編譯另一組語句。
條件編譯命令常用的有以下形式:
1) #ifdef 識別符號
程式段1
#else
程式段2
#endif
它的作用是當所指定的識別符號已經被#define命令定義過,則在程式編譯階段只編譯程式段1,否則編譯程式段2。#endif用來限定#ifdef命令的範圍。其中#else部分也可以沒有。
2) #if 表示式
程式段1
#else
程式段2
#endif
它的作用是當指定的表示式值為真(非零)時就編譯程式段1,否則編譯程式段2。可以事先給定一定條件,使程式在不同的條件下執行不同的功能。
條件編譯是根據實際定義巨集(某類條件)進行**靜態編譯的手段。可根據表示式的值或某個特定巨集是否被定義來確定編譯條件。
最常見的條件編譯是防止重複包含標頭檔案的巨集,形式跟下面**類似:
#ifndef fa_h
#define fa_h
// ... some declaration codes
#endif // #ifndef fa_h
#ifdef _debug
// ... do some operations
#endif
#ifdef _win32
// ... use win32 api
#endif
在除錯程式時,常常希望輸出一些所需的資訊,而在除錯完成後不再輸出這些資訊,可以在源程式中插入條件編譯段。下面是乙個簡單的示例。
#include using namespace std;
#define outputlog //在除錯程式時使之成為注釋行
int main( )
}
#undef可以取消巨集定義,與#define對應。
defined用來測試某個巨集是否被定義。defined(name): 若巨集被定義,則返回1,否則返回0。
它與#if、#elif、#else結合使用來判斷巨集是否被定義,乍一看好像它顯得多餘, 因為已經有了#ifdef和#ifndef。defined可用於在一條判斷語句中宣告多個判別條件;#ifdef和#ifndef則僅支援判斷乙個巨集是否定義。
#if defined(vax) && defined(unix) && !defined(debug)
和#if、#elif、#else不同,#ifdef、#ifndef、defined測試的巨集可以是物件巨集,也可以是函式巨集。
條件編譯中相對常用的預編譯指令。模式如下:
#ifdef abc
// ... codes while definded abc
#elif (code_version > 2)
// ... codes while code_version > 2
#else
// ... remained cases
#endif // #ifdef abc
#ifdef用於判斷某個巨集是否定義,和#ifndef功能正好相反,二者僅支援判斷單個巨集是否已經定義,上面例子中二者可以互換。如果不需要多條件預編譯的話,上面例子中的#elif和#else均可以不寫。
#if可支援同時判斷多個巨集的存在,與常量表示式配合使用。常用格式如下:
#if 常量表示式1
// ... some codes
#elif 常量表示式2
// ... other codes
#elif 常量表示式3
// ...
...#else
// ... statement
#endif
常量表示式可以是包含巨集、算術運算、邏輯運算等等的合法c常量表示式,如果常量表示式為乙個未定義的巨集, 那麼它的值被視為0。
#if macro_non_defined // 等價於 #if 0
在判斷某個巨集是否被定義時,應當避免使用#if,因為該巨集的值可能就是被定義為0。而應當使用#ifdef或#ifndef。
注意: #if、#elif之後的巨集只能是物件巨集。如果巨集未定義,或者該巨集是函式巨集,則編譯器可能會有對應巨集未定義的警告。
c 條件編譯詳解
本篇文章專注於解答在 c 預處理器 一文中提出的問題,並進一步提公升對c 條件編譯的認識。通常,原始檔中所有內容都要參加編譯,但是在某些時候,可能希望原始檔中某些部分在滿足某些條件的情況下才進行編譯,這就是所謂的條件編譯。有趣的是,對於c 的初學者來說,沒有條件編譯照樣可以寫出可以良好執行的程式,所...
C語言條件編譯詳解
預處理程式提供了條件編譯的功能。可以按不同的條件去編譯不同的程式部分,因而產生不同的目標 檔案。這對於程式的移植和除錯是很有用的。條件編譯有三種形式,下面分別介紹 ifdef 識別符號 程式段1 else 程式段2 endif 它的功能是,如果識別符號已被 define命令定義過則對程式段1進行編譯...
c語言條件編譯詳解
指令 用途 空指令,無任何效果 include 包含乙個源 檔案 define 定義巨集 undef 取消已定義的巨集 if 如果給定條件為真,則編譯下面 ifdef 如果巨集已經定義,則編譯下面 ifndef 如果巨集沒有定義,則編譯下面 elif 如果前面的 if給定條件不為真,當前條件為真,則...