深入淺析C++中的#,##,和
想要靈活應(yīng)用宏,離不開(kāi)#和##。
"
在學(xué)習(xí)#和##之前,先來(lái)看一個(gè)關(guān)于"的例子:
#include <stdio.h>
#include <string.h>
int main()
{
const char* p1 = "Hello," "World!"; // 一個(gè)空格
const char* p2 = "Hello," "World!"; // 多個(gè)空格
const char* p3 = "Hello,""World!"; // 沒(méi)有空格
const char* p4 = "Hello,World!"; // 一個(gè)整串
const char* p5 = "Nihao,""Shijie!"; // 一個(gè)不同的串
printf("p1 = %s, strlen(p1) = %d\n", p1, strlen(p1));
printf("p2 = %s, strlen(p2) = %d\n", p2, strlen(p2));
printf("p3 = %s, strlen(p3) = %d\n", p3, strlen(p3));
printf("p4 = %s, strlen(p4) = %d\n", p4, strlen(p4));
printf("p5 = %s, strlen(p5) = %d\n", p5, strlen(p5));
return 0;
}
輸出為:
p1 = Hello,World!, strlen(p1) = 12
p2 = Hello,World!, strlen(p2) = 12
p3 = Hello,World!, strlen(p3) = 12
p4 = Hello,World!, strlen(p4) = 12
p5 = Nihao,Shijie!, strlen(p5) = 13
查看PE文件的常量字符串段,發(fā)現(xiàn)經(jīng)過(guò)編譯器優(yōu)化后只存在一個(gè)Hello,World!串。

即p1,p2,p3,p4這四種寫法是等價(jià)的,這一點(diǎn)作為之后解釋#用法的前提。
字符串化操作(#)
當(dāng)用作字符串化操作時(shí),#的主要作用是將宏參數(shù)不經(jīng)擴(kuò)展地轉(zhuǎn)換成字符串常量。
要點(diǎn):
- 宏定義參數(shù)的左右兩邊的空格會(huì)被忽略,參數(shù)的各個(gè)Token之間的多個(gè)空格會(huì)被轉(zhuǎn)換成一個(gè)空格。
- 宏定義參數(shù)中含有需要特殊含義字符如"或\時(shí),它們前面會(huì)自動(dòng)被加上轉(zhuǎn)義字符\。
還是通過(guò)MSDN上的例子來(lái)看看容易懂:
#define F abc #define B def #define FB(arg) #arg #define FB1(arg) FB(arg) FB(F B) FB1(F B)
初看到時(shí)推測(cè)這兩行預(yù)編譯出來(lái)后效果是一樣的,但是看了使用gcc -E編譯出來(lái)代碼,這才理解了MSDN上對(duì)“不經(jīng)擴(kuò)展”有了更深刻的理解,實(shí)際的預(yù)編譯后代碼為:
"F B"; "abc def";
推測(cè)變換過(guò)程應(yīng)該如下:
FB(F B) --> #F B -->"F B" FB1(F B) --> FB1(abc def) --> FB(abc def) --> #abc def --> "abc def"
標(biāo)記連接操作(##)
將多個(gè)Token連接成一個(gè)Token。
要點(diǎn):
- 它不能是宏定義中的第一個(gè)或最后一個(gè)Token。
- 前后的空格可有可無(wú)。
來(lái)理解一下MSDN上舉的例子:
#include <stdio.h>
#define paster( n ) printf_s( "token" #n " = %d", token##n )
int token9 = 9;
int main()
{
paster(9);
}
paster(9);的預(yù)處理步驟應(yīng)該如下:
- paster(9);
- printf_s( "token" #9 " = %d", token##9 );
- printf_s( "token" "9" " = %d", token9 );
- printf_s( "token9 = %d", token9 );
這樣應(yīng)該就很好理解了。
參考MSDN
Stringizing Operator(#) : http://msdn.microsoft.com/EN-US/library/7e3a913x(v=VS.110,d=hv.2).aspx
Token-Pasting Operator(##) : http://msdn.microsoft.com/EN-US/library/09dwwt6y(v=VS.110,d=hv.2).aspx
到此這篇關(guān)于C++中的#,##,和"的文章就介紹到這了,更多相關(guān)C++中的#,##,和"內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
C++編程中break語(yǔ)句和continue語(yǔ)句的學(xué)習(xí)教程
這篇文章主要介紹了C++編程中break語(yǔ)句和continue語(yǔ)句的學(xué)習(xí)教程,break和continue是C++循環(huán)控制中的基礎(chǔ)語(yǔ)句,需要的朋友可以參考下2016-01-01
C語(yǔ)言開(kāi)發(fā)實(shí)現(xiàn)通訊錄管理系統(tǒng)
這篇文章主要為大家詳細(xì)介紹了C語(yǔ)言開(kāi)發(fā)實(shí)現(xiàn)通訊錄管理系統(tǒng),文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2022-08-08
完全掌握C++編程中構(gòu)造函數(shù)使用的超級(jí)學(xué)習(xí)教程
這篇文章主要介紹了C++中的構(gòu)造函數(shù),包括C++11標(biāo)準(zhǔn)中的新特性的介紹,十分推薦!需要的朋友可以參考下2016-01-01
c++實(shí)現(xiàn)合并文件以及拆分實(shí)例代碼
這篇文章主要介紹了c++實(shí)現(xiàn)合并文件以及拆分實(shí)例代碼,小編覺(jué)得還是挺不錯(cuò)的,具有一定借鑒價(jià)值,需要的朋友可以參考下2018-01-01
Qt基于QScrollArea實(shí)現(xiàn)界面嵌套移動(dòng)
在實(shí)際的應(yīng)用場(chǎng)景中,經(jīng)常會(huì)出現(xiàn)軟件界面戰(zhàn)場(chǎng)圖大于實(shí)際窗體大小。本文將利用QScrollArea可以為widget窗體添加滾動(dòng)條,實(shí)現(xiàn)界面嵌套移動(dòng),感興趣的可以了解一下2022-06-06

