在看《C語言高級(jí)編程》時(shí),里面有個(gè)關(guān)于宏##的題目:
1.已知#define A “menu”
#define B “osd”,
若請使用宏A,B表示出字符串”menuosd”
答案:1 答案1:#define C A B
答案2:#define _C_(a,b) a##b
#define C(a,b) _C_(a,b)
?
然后我實(shí)際動(dòng)手測試了一下,先來第一種:
#include <stdio.h>
#define
A "menu"
#define
B "osd"
#define
STR A B
int
main(
int
argc,
char
*
argv[])
{
char
*p =
STR;
return
0
;
}
gcc -E hell.c -
o hello.i
cat hello.i
結(jié)果:
int main(int argc, char *argv[])
{
char *p = "menu" "osd";
return 0;
}
?
第一個(gè)答案其實(shí)預(yù)編譯后給出的結(jié)果是不完全符合要求的。
然后是第二種:
#include <stdio.h>
#define
A "menu"
#define
B "osd"
#define
_C_(a,b) a##b
#define
C(a,b) _C_(a,b)
int
main(
int
argc,
char
*
argv[])
{
char
*p =
C(A,B);
printf(
"
%s\n
"
, p);
return
0
;
}
?
首先,為什么要定義兩個(gè)宏,一個(gè)不能解決問題嗎?是的,不能。為什么?看這個(gè)鏈接:[
短小精悍的宏
](http://www.cnblogs.com/wb-DarkHorse/archive/2013/04/27/3046749.html)
然后再次按照上邊的命令進(jìn)行預(yù)編譯,但是給出了錯(cuò)誤信息:
pasting "menu" and "osd" does not give a valid preprocessing token gcc
這就奇怪了。然后google了一下,發(fā)現(xiàn)了相同的問題:
[
問題
](http://stackoverflow.com/questions/4667779/preprocessor-macro-gcc-pasting-x-and-x-does-not-give-a-valid-preprocessing-toke)
并且里面說了,這種情況在VS里面不會(huì)報(bào)錯(cuò),可以直接工作。so?
#include <stdio.h>
#define
A "menu"
#define
B "osd"
#define
_C_(a,b) a##b
#define
C(a,b) _C_(a,b)
int
_tmain(
int
argc, _TCHAR*
argv[])
{
char
*p = C(A,B);
//
STR;
printf(
"
%s\n
"
, p);
return
0
;
}
?
果然給出了結(jié)果: menuosd
為什么gcc和VS會(huì)對這個(gè)問題給出差異的結(jié)果呢?看這個(gè)問題:
[
that's why
](http://stackoverflow.com/questions/1206624/differences-in-macro-concatenation-operator-between-visual-c-and-gcc?rq=1)
根據(jù)C標(biāo)準(zhǔn),用##操作后的結(jié)果必須是一個(gè)已經(jīng)預(yù)定義過的符號(hào)。否則是未定義的。所以gcc和vs對于這個(gè)未定義行為表示了不同的看法,前者是給出錯(cuò)誤,后者一笑而過。那什么是已經(jīng)預(yù)定過的符號(hào)呢? 它包含了這些:頭文件名, 等式, 預(yù)處理數(shù)字, 字符常數(shù), 字符串值, 標(biāo)點(diǎn)符號(hào), 單個(gè)非空字符
在我們的例子中,_C_(a,b)用##連接后,應(yīng)該是產(chǎn)生menuosd,但是這是一個(gè)未預(yù)定義的字符串,所以產(chǎn)生了一個(gè)未定義的行為。我們再看一個(gè)例子:
#define
A 2
#define
_CONS(a,b) (a##e##b)
#define
CONS(a,b) _CONS(a,b)
int
main(
int
argc,
char
*
argv[])
{
printf(
"
%f\n
"
, CONS(A, A));
return
0
;
}
?
這個(gè)時(shí)候gcc不會(huì)給出錯(cuò)誤提示了。結(jié)果:200.0000
為什么這個(gè)時(shí)候不給出錯(cuò)誤提示呢?我的理解是,CONS(A, A)替換后成為2e2,而這時(shí)一個(gè)常量,符合C標(biāo)準(zhǔn)。
ok,給出一個(gè)鏈接,詳細(xì)的解釋了gcc中##的用法:
[
gcc concatenation
](http://gcc.gnu.org/onlinedocs/gcc-4.3.3/cpp/Concatenation.html#Concatenation)
?
?
更多文章、技術(shù)交流、商務(wù)合作、聯(lián)系博主
微信掃碼或搜索:z360901061
微信掃一掃加我為好友
QQ號(hào)聯(lián)系: 360901061
您的支持是博主寫作最大的動(dòng)力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點(diǎn)擊下面給點(diǎn)支持吧,站長非常感激您!手機(jī)微信長按不能支付解決辦法:請將微信支付二維碼保存到相冊,切換到微信,然后點(diǎn)擊微信右上角掃一掃功能,選擇支付二維碼完成支付。
【本文對您有幫助就好】元

