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

在頭文件 <stdio.h> 中,getcharputchar 函數在實際中常常被定義為宏,這樣可以避免處理字符時調用函數所需的運行時開銷。<ctype.h> 頭文件中定義的函數也常常是通過宏實現的。

可以通過 #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


參考文獻:

  1. Brian W. Kernighan, Dennis M. Ritchie.The C Programming Language (Second Edition)[M].機械工業出版社:北京,2004:76-77.


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM