C,C 巨集中 和

2021-06-12 16:46:49 字數 2748 閱讀 4877

巨集中的#的功能是將其後面的巨集引數進行字串化操作(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 中,巨集 macro 是屬於編譯時期 而非執行時期 的概念,採用關鍵字define進行定義。它只是一種簡單的字串替換,根據是否帶引數分為無參和帶參。它的作用還是很大的,比如 提高可移植性,可讀性,方便性 等等,常見就是替換變數,防止重複包含標頭檔案等 define max 10 ifn...

c c 巨集中 和 的用法

kennyhe 發表於 2007 2 13 12 25 57 一 一般用法 我們使用 把巨集引數變為乙個字串,用 把兩個巨集引數貼合在一起.用法 i nclude i nclude using namespace std define str s s define cons a,b int a e ...

C C 巨集中「 和 」的用法

一 一般用法 我們使用 把巨集引數變為乙個字串,用 把兩個巨集引數貼合在一起.用法 i nclude i nclude using namespace std define str s s define cons a,b int a e b int main 二 當巨集引數是另乙個巨集的時候 需要注...