C語(yǔ)言中,在宏里面使用’#’和’##’有它非常神奇的作用。在宏定義的替換的過(guò)程中,#號(hào)可以作為一個(gè)預(yù)處理運(yùn)算符,把宏參數(shù)轉(zhuǎn)換為字符串。##運(yùn)算符則可以把兩個(gè)宏參數(shù)組合在一起。下面就來(lái)說(shuō)說(shuō)具體的用法。
1、一般用法
我們使用#把宏參數(shù)變?yōu)橐粋€(gè)字符串,用##把兩個(gè)宏參數(shù)貼合在一起。
下面的代碼是演示代碼:
#include#defineSTRING(s)#s #defineCONNECT(a,b)(int)(a##e##b) intmain(void) { //輸出字符串"abcdefg" printf("string:%s ",STRING(abcdefg)); //2e3輸出:2000 printf("connect:%d ",CONNECT(2,3)); return0; }
運(yùn)行結(jié)果如下圖:
2016-03-21_171313
2、當(dāng)宏參數(shù)是另一個(gè)宏的時(shí)候
需要注意的是:凡是宏定義里有用'#'或'##'的地方,宏參數(shù)是不會(huì)再展開(kāi)。
(1)、非’#’和’##’的情況
#include#defineTOW(2) #defineMUL(a,b)(a*b) intmain(void) { printf("%d*%d=%d ",TOW,TOW,MUL(TOW,TOW)); return0; }
上面代碼中打印那行的宏會(huì)被展開(kāi)為:
printf("%d*%d=%d ",(2),(2),((2)*(2)));
(2)、當(dāng)有'#'或'##'的時(shí)候
#include#include #defineA(2) #defineSTR(s)#s #defineCONS(a,b)(int)(a##e##b) intmain(void) { //INT_MAX這行會(huì)被展開(kāi)為:printf("intmax:%s ","INT_MAX"); printf("intmax:%s ",STR(INT_MAX)); //這一行會(huì)被展開(kāi)為:printf("%s ",(int)(AeA)); printf("%s ",CONS(A,A)); return0; }
上面的代碼在編譯時(shí)會(huì)失敗,INT_MAX和A都不會(huì)再被展開(kāi),然而解決這個(gè)問(wèn)題的方法也很簡(jiǎn)單。加多一層中間轉(zhuǎn)換宏。加這層宏的用意是把所有宏的參數(shù)在這層里全部展開(kāi),那么在轉(zhuǎn)換宏里的那一個(gè)宏(_STR)就能得到正確的宏參數(shù)。
#include#include #defineA2 #define_STR(s)#s #defineSTR(s)_STR(s)//轉(zhuǎn)換宏 #define_CONS(a,b)(int)(a##e##b) #defineCONS(a,b)_CONS(a,b)//轉(zhuǎn)換宏 intmain(void) { //INT_MAX,int型的最大值,為一個(gè)變量 printf("intmax:%s ",STR(INT_MAX)); printf("CONS(A,A):%d ",CONS(A,A)); return0; }
其中代碼:
printf("intmax:%s ",STR(INT_MAX));
輸出為:int max: 2147483647,STR(INT_MAX) ---> _STR(2147483647) 然后再轉(zhuǎn)換成字符串。
第二個(gè)輸出代碼:
printf("CONS(A,A):%d ",CONS(A,A));
輸出為:CONS(A, A):200,CONS(A, A) ---> _CONS(2, 2) ---> int(2e2)。
3、'#'和'##'的一些應(yīng)用特例
(1)、合并匿名變量名
#include#define___ANONYMOUS1(type,var,line)typevar##line #define__ANONYMOUS0(type,line)___ANONYMOUS1(type,_anonymous,line) #defineANONYMOUS(type)__ANONYMOUS0(type,__LINE__) intmain(void) { ANONYMOUS(staticint); _anonymous9=666; printf("_anonymous9:%d ",_anonymous9); return0; }
上述代碼:ANONYMOUS(static int);最終展開(kāi)為:static int _anonymous9; // 9表示該行行號(hào);,下面分析下具體的展開(kāi)過(guò)程:
第一次展開(kāi):ANONYMOUS(static int); ---> __ANONYMOUS0(static int, __LINE__);;
第二次展開(kāi):__ANONYMOUS0(static int, __LINE__); ---> ___ANONYMOUS1(static int, _anonymous, 9);;
第三次展開(kāi):___ANONYMOUS1(static int, _anonymous, 9); ---> static int _anonymous9;;
對(duì)于宏的展開(kāi)過(guò)程,每次只能解開(kāi)當(dāng)前層的宏,所以__LINE__在第二層才能被解開(kāi)。
(2)、獲取文件名
#include#define_GET_FILENAME(filename)#filename #defineGET_FILENAME(filename)_GET_FILENAME(filename) intmain(void) { charfilename[]=GET_FILENAME(__FILE__); printf("filename:%s ",filename); return0; }
當(dāng)然了,上述的宏也可以獲取__DATE__,__LINE__等宏實(shí)際對(duì)應(yīng)的值,上面專(zhuān)門(mén)定義了一個(gè)數(shù)組來(lái)存儲(chǔ)轉(zhuǎn)換后的值,實(shí)際使用時(shí)是否定義數(shù)組可自行安排。
審核編輯:湯梓紅
-
C語(yǔ)言
+關(guān)注
關(guān)注
180文章
7630瀏覽量
140560 -
字符串
+關(guān)注
關(guān)注
1文章
589瀏覽量
21153 -
代碼
+關(guān)注
關(guān)注
30文章
4891瀏覽量
70309 -
運(yùn)算符
+關(guān)注
關(guān)注
0文章
172瀏覽量
11370
原文標(biāo)題:C語(yǔ)言-#和##的神奇作用
文章出處:【微信號(hào):嵌入式那些事,微信公眾號(hào):嵌入式那些事】歡迎添加關(guān)注!文章轉(zhuǎn)載請(qǐng)注明出處。
發(fā)布評(píng)論請(qǐng)先 登錄
C語(yǔ)言typedef與#define的用法和區(qū)別
plsy指令具體用法
discrete filter 與discrete transfer 兩者的具體用法
C語(yǔ)言的位操作在STM32f1單片機(jī)編程的具體應(yīng)用 精選資料推薦
STM32CUBEMX具體詳細(xì)的用法
C語(yǔ)言中的#和##的用法

C語(yǔ)言和C++的特點(diǎn)與用法詳細(xì)說(shuō)明
C語(yǔ)言中的typedef的用法

評(píng)論