#ifdef IDENTIFIER
// 程式段 1:識別符已定義時編譯
#else
// 程式段 2:識別符未定義時編譯
#endif
#ifndef IDENTIFIER
// 程式段 1:識別符未定義時編譯
#else
// 程式段 2:識別符已定義時編譯
#endif
與 #ifdef 作用相反。
#if EXPRESSION
// 運算式為真(非零)編譯程式段 1
#else
// 運算式為假(零)編譯程式段 2
#endif
#ifdef WINDOWS
#define MYTYPE long
#else
#define MYTYPE float
#endif
// Windows 專案編譯前加:#define WINDOWS
#ifdef DEBUG
printf("device_open(%p)\n", file);
#endif
// 除錯時定義 DEBUG,釋出版移除即可統一關閉所有除錯輸出
#define LETTER 1 // 1=大寫輸出, 0=小寫輸出
while ((c = str[i++]) != '\0') {
#if LETTER
if (c >= 'a' && c <= 'z') c -= 32;
#else
if (c >= 'A' && c <= 'Z') c += 32;
#endif
putchar(c);
}
優點:編譯期決定分支,目標碼更小、無執行期判斷開銷。
#ifndef _HEADER_NAME_H_
#define _HEADER_NAME_H_
// 頭檔內容:宣告、定義、內聯函式等
#endif
stdio.h → _STDIO_H_多個 .c 檔包含同一頭檔,連結時會導致重複定義錯誤。護衛模式確保頭檔內容每個編譯單元只被處理一次。
#define VERSION 2
#if VERSION == 1
// 版本 1 程式碼
#elif VERSION == 2
// 版本 2 程式碼
#else
// 預設版本
#endif
__FILE__、__LINE__、__DATE__、__TIME____STDC__、__cplusplus (C++ 模式)_WIN32、__linux__、__APPLE__| 場景 | 推薦寫法 | 關鍵點 |
|---|---|---|
| 頭檔防重複 | #ifndef _GUARD_H_ / #define _GUARD_H_ / #endif | 命名唯一、放最外層 |
| 平台差異 | #ifdef _WIN32 / #else / #endif | 用編譯器預定義巨集 |
| 除錯輸出 | #ifdef DEBUG / ... / #endif | 單一定義控制全域 |
| 版本控制 | #if VERSION == N / #elif / #else / #endif | 集中管理版本常數 |
| 功能裁剪 | #ifdef FEATURE_X / #endif | 編譯期移除未用程式碼 |