文中
__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。
上對preprocessor operators
的講解。
C,C 巨集中 與 的講解
文中 file 與示例1的可以參見 使用ansi c and microsoft c 中常用的預定義巨集 巨集中的 的功能是將其後面的巨集引數進行字串化操作 stringizing operator 簡單說就是在它引用的巨集變數的左右各加上乙個雙引號。如定義好 define string x x之後...
C,C 巨集中 與 的講解
文中 file 與示例1可以參見 使用 ansi c and microsoft c 中常用的預定義巨集 巨集中的 的功能是將其後面的巨集引數進行字串化操作 stringizing operator 簡單說就是在它引用的巨集變數的左右各加上乙個雙引號。如定義好 define string x x之後...
C,C 巨集中 與 的講解
文中 file 與示例1的可以參見 使用ansi c and microsoft c 中常用的預定義巨集 巨集中的 的功能是將其後面的巨集引數進行字串化操作 stringizing operator 簡單說就是在它引用的巨集變數的左右各加上乙個雙引號。如定義好 define string x x之後...