C/C++ 前置處理器提供兩個強大的運算子:`#` (字串化) 與 `##` (符號串聯),支援巨集展開時的文字操作,是建立領域特定語言、自動產生程式碼的關鍵工具。
| 運算子 | 名稱 | 功能 | 僅可用於 |
|---|---|---|---|
| # | Stringification (字串化) | 將巨集參數轉換為字串字面常數 | 巨集定義中,作用於參數 |
| ## | Token Pasting (符號串聯) | 將兩個符號合併為單一符號 | 巨集定義中,連接前後符號 |
#define MZ_PRINT(n) printf("x" #n "=%d", x##n)
int main() {
int x1 = 1;
MZ_PRINT(1); // 展開過程見下
return 0;
}
printf("x1=%d", x1);
#define DECLARE_GETTER(type, name) \
type get_##name() { return name; }
#define DECLARE_SETTER(type, name) \
void set_##name(type value) { name = value; }
int health, mana;
DECLARE_GETTER(int, health) // → int get_health() { return health; }
DECLARE_SETTER(int, mana) // → void set_mana(int value) { mana = value; }
#define CONCAT(a, b) a##b
#define UNIQUE_NAME(prefix) CONCAT(prefix, __LINE__)
int UNIQUE_NAME(temp_) = 0; // → int temp_42 = 0; (假設在第 42 行)
#define LOG_VAR(x) printf(#x " = %d\n", x)
int score = 100;
LOG_VAR(score); // → printf("score = %d\n", score);
#define PASTE(a, b) a##b
#define EXPAND_AND_PASTE(a, b) PASTE(a, b)
#define FOO 100
EXPAND_AND_PASTE(FOO, BAR) // → 100BAR (FOO 先展開為 100)
PASTE(FOO, BAR) // → FOOBAR (直接串聯,不展開 FOO)
#define _CAT(a, b) a##b
#define CAT(a, b) _CAT(a, b) // 第二層觸發參數完整展開
C++11 起提供更安全的替代方案:
掌握 `#` 與 `##` 能讓你在需要巨集元程式設計時遊刃有餘,但記住:「能用語言核心特性解決的,盡量不用巨集」。