C/C 宏替换详解
1. 基本形式
#define?name?replacement_text??復制代碼通常情況下,#define?指令占一行,替換文本是?define?指令行尾部的所有剩余部分,但也可以把一個較長的宏定義分成若干行,這時需要在待續的行末尾加上一個反斜杠符 ``。
宏定義也可以帶參數,這樣可以對不同的宏調用使用不同的替換文本。例:
#define?max(A,?B)?((A)?>?(B)???(A)?:?(B))??復制代碼2. 宏展開中的陷阱
仔細考慮一下?max?的展開式,其中的表達式會被計算兩次,因此如果表達式中包含自增運算符或輸入/輸出等行為,則會出現不正確的情況,例如上述的宏?max:
max(i ,?j )??//?wrong??復制代碼另外還需要注意,適當使用圓括號以保證計算次序的正確性,例如:
#define?square(x)?x?*?x?//?wrong??復制代碼當用?square(z 1)?調用該宏定義時會出錯。
3.?#undef
在頭文件??中,getchar?與?putchar?函數在實際中常常被定義為宏,這樣可以避免處理字符時調用函數所需的運行時開銷。?頭文件中定義的函數也常常是通過宏實現的。
可以通過?#define?取消名字的宏定義,這樣做可以保證后續的調用是函數調用,而不是宏調用:
#undef?getchar?int?getchar(void)?{?...?}??復制代碼4. 宏參數、#?和?##
如果在宏定義的替換文本中,參數名以?#?作為前綴則結果將被擴展為由實際參數替換該參數的帶引號的字符串。例如,可以將它與字符串連接運算結合起來編寫一個調試打印宏:
#define?dprint(expr)?printf(#expr?"?=?%gn",?expr)??復制代碼使用語句
dprint(x/y);??復制代碼調用該宏時,該宏將被擴展為:
printf("x/y"?"?=?%gn",?x/y);??復制代碼其中的字符串被拼接起來了,這樣,該宏調用的效果等價于
printf("x/y?=?%gn",?x/y);??復制代碼預處理器運算符?##?為宏擴展提供了一種連接實際參數的手段。如果替換文本中的參數與?##?相鄰,則該參數將被實際參數替代,##?與前后的空白符將被刪除,并對替換后的結果重新掃描。例如,下面定義的宏?paste?用于連接兩個參數:
#define?paste(front,?back)?front?##?back??復制代碼因此,宏調用?paste(name, 1)?的結果將建立記號?name1。
來源:https://juejin.cn/post/6896453412746395656
總結
 
                            
                        - 上一篇: C 之父:精通C 很难,但你一天之内
- 下一篇: Linux文件服务器搭建(linux文件
