C語言中文網 目錄
首頁 > 編程筆記 > C語言筆記 閱讀:4,690

C語言條件編譯(#if,#ifdef,#ifndef,#endif,#else,#elif)

條件編譯(conditional compiling)命令指定預處理器依據特定的條件來判斷保留或刪除某段源代碼。例如,可以使用條件編譯讓源代碼適用于不同的目標系統,而不需要管理該源代碼的各種不同版本。

條件編譯區域以 #if、#ifdef 或 #ifndef 等命令作為開頭,以 #endif 命令結尾。條件編譯區域可以有任意數量的 #elif 命令,但最多一個 #else 命令。以 #if 開頭的條件編譯區域具有下面的格式:
#if 表達式1
  [ 組1]
[#elif 表達式2
  [ 組2]]
...
[#elif 表達式n
  [ 組n ]]
[#else
  [ 組n+1 ]]
#endif

預處理器會依次計算條件表達式,直到發現結果非 0(也就是 true)的條件表達式。預處理器會保留對應組內的源代碼,以供后續處理。如果找不到值為 true 的表達式,并且該條件式編譯區域中包含 #else 命令,則保留 #else 命令組內的代碼。

組 1、組 2 等代碼段,可以包含任意 C 源代碼,也可以包含更多的命令,包括嵌套的條件式編譯命令。在預處理階段結束時,沒有被預處理器保留以用于后續處理的組會從程序中全部刪除。

#if 和 #elif 命令

作為 #if 或 #elif 命令條件的表達式,必須是整數常量預處理器表達式。這與普通的整數常量表達式不同,主要區別在于:

(1) 不能在 #if 或 #elif 表達式中使用類型轉換運算符。

(2) 可以使用預處理運算符 defined。

(3) 在預處理器展開所有宏,并且計算完所有 defined 表達式之后,會使用字符 o 替換掉表達式中所有其他標識符或關鍵字。

(4) 表達式中所有帶符號值都具有 intmax_t 類型,并且所有無符號值都具有 uintmax_t 類型。字符常量也會受該規則的影響。intmax_t 和 uintmax_t 定義在頭文件 stdint.h 中。

(5) 預處理器會把字符常量和字符串字面量中的字符與轉義序列轉換成運行字符集中對應的字符。然而,字符常量在預處理器表達式和在后期編譯階段是否具有相同的值,取決于實現版本。

defined 運算符

一元運算符 defined 可以出現在 #if 或 #elif 命令的條件中。它的形式如下:
defined 標識符
defined (標識符)

如果指定的  identifier 是一個宏名稱(也就是說,它已被 #define 命令定義,并且未被 #undef 命令取消定義),則 defined 表達式會生成值 1。否則,defined 表達式會生成值 0。

defined 運算符相對于 #ifdef 和 #ifndef 命令的優點是:你可以在更大型的預處理器表達式中使用它的值。如下例所示:
#if defined( __unix__ ) && defined( __GNUC__ )
/* ... */
#endif

大多數編譯器會提供預定義宏,例如上例所使用的宏,它用來識別目標系統和編譯器。因此,在 Unix 系統中,通常預先定義好了宏 __unix__,而 GCC 編譯器則會預先定義好了宏 __GNUC__。類似地,微軟 Windows 平臺上的 Visual C 編譯器會自動定義好宏 _WIN32 和宏 _MSC_VER。

#ifdef 和 #ifndef 命令

可以通過 #ifdef 和 #ifndef 命令測試某個宏是否已被定義。它們的語法是:
#ifdef 標識符
#ifndef 標識符

這等同于下面的 #if 命令:
#if defined 標識符
#if !defined 標識符

如果 identifier 不是宏名稱,則 #ifndef 標識符后面的條件代碼被保留。

精美而實用的網站,提供C語言C++STLLinuxShellJavaGo語言等教程,以及socketGCCviSwing設計模式JSP等專題。

Copyright ?2011-2018 biancheng.net, 陜ICP備15000209號

底部Logo