C語言中條件編譯相關的預編譯指令

2021-10-03 13:04:23 字數 2995 閱讀 5664

本文主要介紹c語言的條件編譯指令

條件編譯是根據實際定義巨集(某類條件)進行**靜態編譯的手段。可根據表示式的值或某個特定巨集是否被定義來確定編譯條件。

最常見的條件編譯是防止重複包含標頭檔案的巨集,形式跟下面**類似:

#ifndef abcd_h

#define abcd_h

// ... some declaration codes

#endif

// #ifndef abcd_h

在實現檔案中通常有如下類似的定義:

#ifdef _debug

// ... do some operations

#endif

#ifdef _win32

// ... use win32 api

#endif

這些都是條件編譯的常用情境。

#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配合使用,判斷某個巨集是否被定義

#define命令定義乙個巨集:

#define macro_name[(args)] [tokens[(opt)]]

之後出現的macro_name將被替代為所定義的標記(tokens)。巨集可帶引數,而後面的標記也是可選的。

巨集定義,按照是否帶引數通常分為物件巨集、函式巨集兩種。

物件巨集: 不帶引數的巨集被稱為"物件巨集(objectlike macro)"。物件巨集多用於定義常量、通用標識。例如:

// 常量定義

#define max_length 100

// 通用標識,日誌輸出巨集

#define slog printf

// 預編譯巨集

#define _debug

函式巨集:帶引數的巨集。利用巨集可以提高**的執行效率: 子程式的呼叫需要壓棧出棧, 這一過程如果過於頻繁會耗費掉大量的cpu運算資源。 所以一些**量小但執行頻繁的**如果採用帶引數巨集來實現會提高**的執行效率。但多數c++程式不推薦使用函式巨集,除錯上有一定難度,可考慮使用c++的inline代替之。例如:

// 最小值函式

#define min(a,b) ((a)>(b)? (a):(b))

// 安全釋放記憶體函式

#define safe_delete(p) }

#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語言中有關預編譯的指令。撰寫本文的目的在於理清相關概念呼叫,在後續預編譯使用時可以找到最合適的指令及格式。比如同時滿足多個巨集定義的預編譯、多分支預編譯、#elif和#else指令的配合等。

c語言中條件編譯相關的預編譯指令

條件編譯是根據實際定義巨集 某類條件 進行 靜態編譯的手段。可根據表示式的值或某個特定巨集是否被定義來確定編譯條件。最常見的條件編譯是防止重複包含標頭檔案的巨集,形式跟下面 類似 1 ifndef abcd h 2 define abcd h34 some declaration codes56 e...

c語言中條件編譯相關的預編譯指令

條件編譯是根據實際定義巨集 某類條件 進行 靜態編譯的手段。可根據表示式的值或某個特定巨集是否被定義來確定編譯條件。最常見的條件編譯是防止重複包含標頭檔案的巨集,形式跟下面 類似 1 ifndef abcd h 2 define abcd h34 some declaration codes56 e...

c語言中預編譯

預編譯又被稱為預處理,是做 文字的替換工作。處理 開頭的指令。就是為編譯做預備工作的準備。常見的預編譯指令有三種 1 include指令 該指令指示編輯器將 檔案的全部內容插入此處,如果使用 代表在系統指定目錄下搜尋檔案,使用 代表現在當前目錄下搜尋檔案,然後在系統預設目錄下搜尋。2 define指...