條件編譯,C語言條件編譯詳解

2020-07-16 10:04:23
條件編譯是指前處理器根據條件編譯指令,有條件地選擇源程式程式碼中的一部分程式碼作為輸出,送給編譯器進行編譯。主要是為了有選擇性地執行相應操作,防止宏替換內容(如檔案等)的重複包含。常見的條件編譯指令如表 1 所示。

表 1 常見的條件編譯指令
條件編譯指令 說 明
#if 如果條件為真,則執行相應操作
#elif 如果前面條件為假,而該條件為真,則執行相應操作
#else 如果前面條件均為假,則執行相應操作
#endif 結束相應的條件編譯指令
#ifdef 如果該宏已定義,則執行相應操作
#ifndef 如果該宏沒有定義,則執行相應操作

#if-#else-#endif

其呼叫格式為:

#if 條件表示式
    程式段1
#else
    程式段2
#endif

功能為:如果#if後的條件表示式為真,則程式段 1 被選中,否則程式段 2 被選中。

注意,必須使用 #endif 結束該條件編譯指令。

例如:
#include<stdio.h>
#define RESULT 0//定義 RESULT 為 0
int main (void)
{
    #if !RESULT //或者 0==RESULT
        printf("It's False!n");
    #else
        printf("It's True!n");
    #endif //標誌結束#if
        return 0;
}
上述程式中,首先定義了 RESULT 為 0,在 main 中使用 #if-#else-#endif 條件判斷語句,如果 RESULT 為 0,則輸出 It's False!,否則輸出 It's True!。本例輸出為:It's False!。

#ifndef-#define-#endif

其呼叫格式為:

#ifndef 識別符號
#define 識別符號 替換列表
    //...
#endif

功能為:一般用於檢測程式中是否已經定義了名字為某識別符號的宏,如果沒有定義該宏,則定義該宏,並選中從 #define 開始到 #endif 之間的程式段;如果已定義,則不再重複定義該符號,且相應程式段不被選中。

例如:
#ifndef PI
#define PI 3.1416
#endif
上述程式段,用於判斷是否已經定義了名為 PI 的宏,如果沒有定義 PI,則執行如下宏定義。
#define PI 3.1416
如果檢測到已經定義了 PI,則不再重複執行上述宏定義。

該條件編譯指令更重要的一個應用是防止標頭檔案重複包含。

如果 f.c 原始檔中包含 f1.h 和 f2.h 兩個標頭檔案,而 f1.h 標頭檔案及 f2.h 標頭檔案中均包含 x.h 標頭檔案,則 f.c 原始檔中重複包含 x.h 標頭檔案。可採用條件編譯指令,來避免標頭檔案的重複包含問題。所有標頭檔案中都按如下格式:

#ifndef _HEADNAME_H_
#define _HEADNAME_H_
    //標頭檔案內容
#endif

當該標頭檔案第一次被包含時,由於沒檢測到該標頭檔案名對應的符號(宏名)_HEADNAME_H_,則定義該標頭檔案名對應的符號(宏),其值為該系統預設。並且,該條件編譯指令選中 #endif 之前的標頭檔案內容;如果該標頭檔案再次被包含時,由於檢測到已存在以該標頭檔案名對應的符號(宏名),則忽略該條件編譯指令之間的所有程式碼,從而避免了重複包含。

#if-#elif-#else-#endif

其呼叫格式為:

#if 條件表示式1
    程式段 1
#elif 條件表示式2
    程式段 2
#else
    程式段3
#endif

功能為:先判斷條件1的值,如果為真,則程式段 1 被選中編譯;如果為假,而條件表示式 2 的值為真,則程式段 2 被選中編譯;其他情況,程式段 3 被選中編譯。

#ifdef-#endif

其呼叫格式為:

#ifdef 識別符號
    程式段
#endif

功能為:如果檢測到已定義該識別符號,則選擇執行相應程式段被選中編譯;否則,該程式段會被忽略。

例如:
#ifdef N
#undef N
    //程式段
#endif
功能:如果檢測到符號 N 已定義,則刪除其定義,並選中相應的程式段。