日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > c/c++ >内容正文

c/c++

C,C++宏中#与##的讲解

發布時間:2025/3/8 c/c++ 29 豆豆
生活随笔 收集整理的這篇文章主要介紹了 C,C++宏中#与##的讲解 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
文中__FILE__與示例1可以參見《使用ANSI C and Microsoft C++中常用的預定義宏》

宏中的#的功能是將其后面的宏參數進行字符串化操作(Stringizing operator),簡單說就是在它引用的宏變量的左右各加上一個雙引號。

如定義好#define?STRING(x)?#x之后,下面二條語句就等價。

?????? char *pChar?=?"hello";

?????? char *pChar?=?STRING(hello);

還有一個#@是加單引號(Charizing Operator

#define?makechar(x)?#@x

?????? char?ch?=?makechar(b);char?ch?=?'b';等價。

?

但有小問題要注意,宏中遇到###時就不會再展開宏中嵌套的宏了。什么意思了?比如使用char *pChar?=?STRING(__FILE__);雖然__FILE__本身也是一個宏,但編譯器不會展開它,所以pChar將指向"__FILE__"而不是你要想的形如"D:\XXX.cpp"的源文件名稱。因此要加一個中間轉換宏,先將__FILE__解析成"D:\XXX.cpp"字符串。

定義如下所示二個宏:

#define?_STRING(x)?#x

#define?STRING(x)?_STRING(x)

再調用下面語句將輸出帶""的源文件路徑

?????? char*?pChar?=?STRING(__FILE__);

???????printf("%s %s\n",?pChar, __FILE__);

可以比較下STRING(__FILE__)__FILE__的不同,前將帶雙引號,后一個沒有雙引號。

?

再講下##的功能,它可以拼接符號(Token-pasting operator)。

MSDN上有個例子:

#define?paster(?n?)?printf(?"token"#n" = %d\n", token##n?)

int?token9?= 100;

再調用??paster(9);宏展開后token##n直接合并變成了token9。整個語句變成了

printf(?"token""9"" = %d", token9 );

C語言中字符串中的二個相連的雙引號會被自動忽略,于是上句等同于

printf("token9 = %d", token9);。

即輸出token9 = 100

?

?

有了上面的基礎后再來看示例1

#define?WIDEN2(x) L?##?x

#define?WIDEN(x)?WIDEN2(x)

#define?__WFILE__?WIDEN(__FILE__)

wchar_t?*pwsz?=?__WFILE__;

第一個宏中的L是將ANSI字符串轉化成unicode字符串。如:wchar_t?*pStr?= L"hello";

再來看wchar_t?*pwsz?=?__WFILE__;

__WFILE__被首先展開成WIDEN(__FILE__),再展開成WIDEN2("__FILE__表示的字符串"),再拼接成?L"__FILE__表示的字符串"?L"D:\XXX.cpp"?從而得到unicode字符串并取字符串地址賦值給pwsz指針。

?

VC_T()TEXT?()也是用的這種技術。

tchar.h頭文件中可以找到:

#define?_T(x)???????__T(x)

#define?__T(x)???? L?##?x

winnt.h頭文件中可以找到

#define?TEXT(quote)?__TEXT(quote)???// r_winnt

#define?__TEXT(quote) L##quote?????// r_winnt

因此不難理解為什么第三條語句會出錯error C2065: 'LszText' : undeclared identifier

???????wprintf(TEXT("%s %s\n"),?_T("hello"),?TEXT("hello"));

?????? char?szText[] =?"hello";

???????wprintf(TEXT("%s %s\n"),?_T(szText),?TEXT(szText));

而將"hello"定義成宏后就能正確運行。

#define?SZTEXT?"hello"

???????wprintf(TEXT("%s %s\n"),?_T(SZTEXT),?TEXT(SZTEXT));

注:由于VC6.0默認是ANSI編碼,因此要先設置成unicode編碼,在project菜單中選擇Setting,再在C/C++標簽對話框中的Category中選擇Preprocessor。再地Preprocessor definitions編輯框中將_MBCS去掉,加上_UNICODE,UNICODE。

轉載于:https://www.cnblogs.com/cyjsegull/p/4526296.html

總結

以上是生活随笔為你收集整理的C,C++宏中#与##的讲解的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。