C语言中,在宏里面使用’#’和’##’有它非常神奇的作用。在宏定义的替换的过程中,#号可以作为一个预处理运算符,把宏参数转换为字符串。##运算符则可以把两个宏参数组合在一起。下面就来说说具体的用法。
1、一般用法
我们使用#把宏参数变为一个字符串,用##把两个宏参数贴合在一起。
下面的代码是演示代码:
#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; }
运行结果如下图:
2016-03-21_171313
2、当宏参数是另一个宏的时候
需要注意的是:凡是宏定义里有用'#'或'##'的地方,宏参数是不会再展开。
(1)、非’#’和’##’的情况
#include#defineTOW(2) #defineMUL(a,b)(a*b) intmain(void) { printf("%d*%d=%d ",TOW,TOW,MUL(TOW,TOW)); return0; }
上面代码中打印那行的宏会被展开为:
printf("%d*%d=%d ",(2),(2),((2)*(2)));
(2)、当有'#'或'##'的时候
#include#include #defineA(2) #defineSTR(s)#s #defineCONS(a,b)(int)(a##e##b) intmain(void) { //INT_MAX这行会被展开为:printf("intmax:%s ","INT_MAX"); printf("intmax:%s ",STR(INT_MAX)); //这一行会被展开为:printf("%s ",(int)(AeA)); printf("%s ",CONS(A,A)); return0; }
上面的代码在编译时会失败,INT_MAX和A都不会再被展开,然而解决这个问题的方法也很简单。加多一层中间转换宏。加这层宏的用意是把所有宏的参数在这层里全部展开,那么在转换宏里的那一个宏(_STR)就能得到正确的宏参数。
#include#include #defineA2 #define_STR(s)#s #defineSTR(s)_STR(s)//转换宏 #define_CONS(a,b)(int)(a##e##b) #defineCONS(a,b)_CONS(a,b)//转换宏 intmain(void) { //INT_MAX,int型的最大值,为一个变量 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) 然后再转换成字符串。
第二个输出代码:
printf("CONS(A,A):%d ",CONS(A,A));
输出为:CONS(A, A):200,CONS(A, A) ---> _CONS(2, 2) ---> int(2e2)。
3、'#'和'##'的一些应用特例
(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);最终展开为:static int _anonymous9; // 9表示该行行号;,下面分析下具体的展开过程:
第一次展开:ANONYMOUS(static int); ---> __ANONYMOUS0(static int, __LINE__);;
第二次展开:__ANONYMOUS0(static int, __LINE__); ---> ___ANONYMOUS1(static int, _anonymous, 9);;
第三次展开:___ANONYMOUS1(static int, _anonymous, 9); ---> static int _anonymous9;;
对于宏的展开过程,每次只能解开当前层的宏,所以__LINE__在第二层才能被解开。
(2)、获取文件名
#include#define_GET_FILENAME(filename)#filename #defineGET_FILENAME(filename)_GET_FILENAME(filename) intmain(void) { charfilename[]=GET_FILENAME(__FILE__); printf("filename:%s ",filename); return0; }
当然了,上述的宏也可以获取__DATE__,__LINE__等宏实际对应的值,上面专门定义了一个数组来存储转换后的值,实际使用时是否定义数组可自行安排。
审核编辑:汤梓红
-
C语言
+关注
关注
180文章
7604浏览量
136675 -
字符串
+关注
关注
1文章
578浏览量
20505 -
代码
+关注
关注
30文章
4779浏览量
68516 -
运算符
+关注
关注
0文章
172浏览量
11078
原文标题:C语言-#和##的神奇作用
文章出处:【微信号:嵌入式那些事,微信公众号:嵌入式那些事】欢迎添加关注!文章转载请注明出处。
发布评论请先 登录
相关推荐
评论