C 標準規定:#define 替換發生於**前置處理階段**,字串常數 ("...") 內的字元**不參與**巨集參數替換,也不進行 ## 連接。
#define out(x) "billd##(x)##.gif" // 錯誤:字串內不處理
#define out(x) "billd"##(x)##".gif" // 錯誤:## 不能連接字串常數與括號
#define out(x) "billd"##"(x)"##".gif" // 錯誤:同理
以上皆會輸出字面文字 billd(x).gif 或編譯錯誤。
#define STR(x) #x // 字串化運算子:將參數變為字串常數
#define CAT(a,b) a##b // 連接運算子
#define OUT(x) "billd" STR(x) ".gif"
// 展開過程:OUT(5) → "billd" STR(5) ".gif" → "billd" "5" ".gif" → "billd5.gif"
#define FMT(fmt, ...) printf(fmt, __VA_ARGS__)
// 使用:FMT("billd%d.gif\n", 5);
## 是**記號連接**,運作於**前置處理記號**層級,字串常數是**單一記號**,內部結構不可見。# 將記號轉為字串常數,**發生在參數替換之後**,因此可用於參數值。#x 字串化參數,依賴相鄰字串常數自動連接。printf/snprintf,勿嘗試巨集模擬。#define SQR(x) ((x)*(x))。