文中__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:\***.cpp"的原始檔名稱。因此要加乙個中間轉換巨集,先將__file__解析成"
d:\***.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:\***.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。
的講解。
C C 巨集詳解
c c 巨集詳解 眾多c 書籍都忠告我們c語言巨集是萬惡之首,但事情總不如我們想象的那麼壞 眾多c 書籍都忠告我們c語言巨集是萬惡之首,但事情總不如我們想象的那麼壞,就如同goto一樣。巨集有 乙個很大的作用,就是自動為我們產生 如果說模板可以為我們產生各種型別的 型別替換 那麼巨集其實可以為我們在...
C C 巨集詳解
眾多c 書籍都忠告我們c語言巨集是萬惡之首,但事情總不如我們想象的那麼壞,就如同goto一樣。巨集有 乙個很大的作用,就是自動為我們產生 如果說模板可以為我們產生各種型別的 型別替換 那麼巨集其實可以為我們在符號上產生新的 即符號替換 增加 關於巨集的一些語法問題,可以在google上找到。相信我,...
C C 巨集替換詳解
define name replacement text 複製 通常情況下,define指令佔一行,替換文字是define指令行尾部的所有剩餘部分,但也可以把乙個較長的巨集定義分成若干行,這時需要在待續的行末尾加上乙個反斜槓符 巨集定義也可以帶引數,這樣可以對不同的巨集呼叫使用不同的替換文字。例 d...