| 宏定義 | 功能 | 示例 | 結果 |
|---|---|---|---|
#define EC(x) L##x | Token 連接:將 L 與參數融合為寬字符字面量 | EC(hello) | L"hello" |
#define Conn(x,y) x##y | Token 連接:融合兩個參數 | Conn(123,456) | 123456 |
#define ToChar(x) #@x | 字符化:用單引號包裹參數 | ToChar(1) | '1' |
#define ToString(x) #x | 字符串化:用雙引號包裹參數 | ToString(123132) | "123132" |
## 由兩個井號組成,用於帶參數宏定義中將兩個 token(語法最小單元)連接成新 token。注意:它不能位於第一個或最後一個 token 位置。
int n = Conn(123, 456); // n = 123456
char* str = Conn("asdf", "adf"); // str = "asdfadf"
# 將傳入參數視為字面文本,用雙引號包裹成字符串常量。#@ 則用單引號包裹成字符常量。
ToChar(123) → '3'(取最後一字符)C2015: too many characters in constant#define paster(n) printf("token" #n " = %d", token##n)
int token9 = 9;
paster(9);
預處理展開:
printf("token" "9" " = %d", token9);
// 即 printf("token9 = %d", token9);
// 輸出:token9 = 9
關鍵機制:9 同時被 #n 字符串化為 "9",又被 token##n 連接為 token9。
printf("" #name "") 為何輸出 name 而非 "#name"?#define display(name) printf("" #name "")
display(name); // 展開為 printf("" "name" "") → printf("name")
相鄰字符串字面量自動連接,#name 變為 "name",外層空串 "" 合併後等價於 printf("name")。
print(x) 系列實驗#define print(x) printf(#x)
print(123); // printf("123") → 輸出 123
print("123"); // printf("\"123\"") → 輸出 "123"
print("\n"); // printf("\"\\n\"") → 輸出 "\n"
# 會保留參數原始拼寫,包括引號與轉義字符。
##:Token-pasting operator(標記連接操作符)#:Stringizing operator(字符串化操作符)#@:Charizing operator(字符化操作符,Microsoft 擴展)" 會自動轉義為 \",\ 變為 \\/P 編譯選項生成 .i 預處理文件constexpr、模板、內聯函數