深入淺析C++中的#,##,和
想要靈活應(yīng)用宏,離不開#和##。
"
在學(xué)習(xí)#
和##
之前,先來看一個(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!"; // 沒有空格 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)過編譯器優(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)義字符\。
還是通過MSDN上的例子來看看容易懂:
#define F abc #define B def #define FB(arg) #arg #define FB1(arg) FB(arg) FB(F B) FB1(F B)
初看到時(shí)推測(cè)這兩行預(yù)編譯出來后效果是一樣的,但是看了使用gcc -E編譯出來代碼,這才理解了MSDN上對(duì)“不經(jīng)擴(kuò)展”有了更深刻的理解,實(shí)際的預(yù)編譯后代碼為:
"F B"; "abc def";
推測(cè)變換過程應(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。
- 前后的空格可有可無。
來理解一下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++11?成員函數(shù)作為回調(diào)函數(shù)的使用方式
這篇文章主要介紹了C++11?成員函數(shù)作為回調(diào)函數(shù)的使用方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-11-11C++中的QCommandLineParser簡(jiǎn)介
這篇文章主要介紹了QCommandLineParser是Qt框架中的一個(gè)類,用于簡(jiǎn)化命令行參數(shù)的解析和處理,它支持定義命令行選項(xiàng)、解析參數(shù)、驗(yàn)證輸入有效性,并自動(dòng)生成幫助文本,適用于各種需要命令行輸入的應(yīng)用程序2024-09-09C語言連接并操作Sedna XML數(shù)據(jù)庫(kù)的方法
這篇文章主要介紹了C語言連接并操作Sedna XML數(shù)據(jù)庫(kù)的方法,實(shí)例分析了C語言操作XML文件的相關(guān)技巧,需要的朋友可以參考下2015-06-06