#ifdef / #ifndef / #if / #else / #endif 完全指南條件編譯讓源碼部分內容僅在滿足特定條件時參與編譯,提高代碼可移植性與可配置性。
#ifdef IDENTIFIER
// 程序段 1:IDENTIFIER 已定義時編譯
#else
// 程序段 2:未定義時編譯 (可省略)
#endif
#ifndef IDENTIFIER:未定義時編譯程序段 1,與 #ifdef 邏輯相反。#if EXPRESSION:表達式非零(真)編譯程序段 1,零(假)編碼段 2。表達式可含定義的宏常量。#ifdef WINDOWS
#define MYTYPE long
#else
#define MYTYPE float
#endif
Windows 編譯前定義 #define WINDOWS,其他平台不定義。同一源碼無需修改即可適配多平台。
#ifdef DEBUG
printf("device_open(%p)\n", file);
#endif
調試時定義 #define DEBUG,發布時刪除該行,所有 DEBUG 區塊自動失效,如同總開關,避免手動刪改大量 printf。
#define LETTER 1
// ...
#if LETTER
if (c >= 'a' && c <= 'z') c = c - 32; // 轉大寫
#else
if (c >= 'A' && c <= 'Z') c = c + 32; // 轉小寫
#endif
修改 LETTER 為 0/1 即可切換功能,目標代碼更精簡(未編譯分支不生成指令)。
#ifdef HNLD 包含特定客戶模塊 #include "n166_hn.c"。發布其他客戶版本時僅註釋宏定義。#ifdef DEBUG printf("Now in ...\n"); #endif。#ifndef TEST i = dial(); #else i = 0; #endif。調試通過後屏蔽 TEST 發布。#ifndef _STDIO_H_
#define _STDIO_H_
// ... 頭文件內容 ...
#endif
stdio.h → _STDIO_H_。// 錯誤示範
#ifndef AAA
#define AAA
int i; // 定義變量
#endif
多 .cpp 包含此頭文件並鏈接時,C++ 報「重複定義」;C 可能通過(弱符號機制)。
解決:頭文件只 extern int i; 聲明,在一個 .c/.cpp 中定義 int i;。
#ifdef/#ifndef 檢查宏是否定義;#if 判斷表達式真假。