C,C 巨集中 與 的講解

2022-09-10 14:21:25 字數 3785 閱讀 3185

文中

__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

) #@

xchar 

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 巨集中 與 的講解

文中 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之後...