預處理器根據常量表達式值或宏定義狀態,決定哪些代碼參與編譯。實現跨平台適配、調試開關、版本裁剪、防重複包含等核心功能。
| 指令 | 功能 | 典型用法 |
|---|---|---|
#if expr | 表達式非零則編譯後續代碼 | #if DEBUG_LEVEL > 2 |
#ifdef MACRO | 宏已定義則編譯 | #ifdef __linux__ |
#ifndef MACRO | 宏未定義則編譯 | #ifndef _HEADER_H_ (防重複包含) |
#elif expr | 前條件假且當前真則編譯 | #elif defined(WIN32) |
#else | 前條件假則編譯 | 備選分支 |
#endif | 結束條件編譯塊 | 必須配對 |
#error msg | 強制編譯錯誤並輸出信息 | #error "Unsupported platform" |
#define DEBUG 0
#if DEBUG
#define LOG(fmt, ...) printf(fmt, ##__VA_ARGS__)
#else
#define LOG(fmt, ...) // 釋出版無日誌開銷
#endif
// 等價於移除 #define DEBUG 行
注意:#if 後只能跟整型常量表達式,可用 defined(MACRO) 檢查宏定義。
// 防重複包含標準模式
#ifndef _MY_HEADER_H_
#define _MY_HEADER_H_
// 內容...
#endif
// 平台適配
#ifdef _WIN32
#include
#define PATH_SEP '\\'
#elif defined(__linux__)
#include
#define PATH_SEP '/'
#elif defined(__APPLE__)
#include
#define PATH_SEP '/'
#else
#error "Unsupported OS"
#endif
#define VERSION 2
#if VERSION == 1
void feature_v1() { ... }
#elif VERSION == 2
void feature_v2() { ... }
#elif VERSION == 3
void feature_v3() { ... }
#else
#error "Unknown VERSION"
#endif
// 檢查多個宏任一已定義
#if defined(DEBUG) || defined(VERBOSE)
#define TRACE_ON 1
#endif
// 檢查宏未定義
#if !defined(NDEBUG)
#define ASSERT(x) if(!(x)) abort()
#else
#define ASSERT(x)
#endif
#if !defined(CONFIG_FILE) && !defined(DEFAULT_CONFIG)
#error "Must define CONFIG_FILE or DEFAULT_CONFIG"
#endif
#define LOG_LEVEL 2 // 0=關閉, 1=錯誤, 2=警告, 3=信息, 4=調試
#if LOG_LEVEL >= 1
#define LOG_E(fmt, ...) fprintf(stderr, "[E] " fmt, ##__VA_ARGS__)
#else
#define LOG_E(fmt, ...)
#endif
#if LOG_LEVEL >= 2
#define LOG_W(fmt, ...) fprintf(stderr, "[W] " fmt, ##__VA_ARGS__)
#else
#define LOG_W(fmt, ...)
#endif
// ...
#if defined(__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6))
#define HAS_CONSTEXPR 1
#else
#define HAS_CONSTEXPR 0
#endif
// 傳統
#ifndef _FOO_H_
#define _FOO_H_
...
#endif
// C23 / 現代編譯器支援 #pragma once (非標準但普遍支援)
#pragma once
...
defined() 顯式檢查。#else COND 是錯誤語法,#else 無條件。條件編譯是 C 語言靜態多態的核心手段。善用 #if/#ifdef/#ifndef/#elif/#else/#endif 實現:
原則:條件保持簡單、分支邏輯清晰、避免深度嵌套、配合版本控制管理配置宏。