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:\***.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
去掉,加上
上對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之後...