C语言中宏有两个非常有用的宏符号“#”,“##”这两个符号的用法总结如下。
#把宏参数变为一个字符串,而##把两个宏参数贴合在一起。
一、一般用法:
#include<stdio.h>
#defineSTR(s)#s
#defineCONSS(a,b)(int)a##e##b
intmain()
{
printf(STR(vck));//输出字符串"vck"
printf("\n");
printf("%d\n",CONSS(2,3));//2e3输出:2000
return0;
}
二、宏参数是另一个宏
1、非’#’和’##’的情况:
#include<stdio.h>
#defineTOW(2)
#defineMUL(a,b)(a*b)
intmain()
{
printf("%d*%d=%d\n",TOW,TOW,MUL(TOW,TOW));
return0;
}
展开的结果是:
printf("%d*%d=%d\n",(2),(2),((2)*(2)));
所以:没有使用#符号时,会递归的全部展开。
2、当有’#’或’##’的时候
需要注意的是凡宏定义里有用’#’或’##’的地方宏参数是不会再展开。如下:
#include<stdio.h>
#defineINT_MAX0x7fffffff
#defineSTR(s)#s
intmain()
{
printf("intmax:%s\n",STR(INT_MAX));//输出:intmax:INT_MAX
printf("intmax:%d\n",INT_MAX);//输出:intmax:2147483647
return0;
}
如果定义:
#include<stdio.h>
#defineA(2)
#defineCONSS(a,b)(int)a##e##b
intmain()
{
printf("%d\n",CONSS(A,A));
return0;
}
则编译时会报错,因为无法将A展开,所以(int)(2)e(2)会出错。
解决办法:加多一层中间转换宏。加这层宏的用意是把所有宏的参数在这层里全部展开,那么在转换宏里的那一个宏就能得到正确的宏参数。
#include<stdio.h>
#defineA2
#define_STR(s)#s
#defineSTR(s)_STR(s)//转换宏
#define_CONSS(a,b)(int)a##e##b
#defineCONSS(a,b)_CONSS(a,b)//转换宏
intmain()
{
printf("%d\n",CONSS(A,A));
printf("%d\n",STR(A));
return0;
}
三、’#’和’##’的一些应用特例
1、合并匿名变量名
#define___ANONYMOUS1(type,var,line)typevar##line
#define__ANONYMOUS0(type,line)___ANONYMOUS1(type,_anonymous,line)
#defineANONYMOUS(type)__ANONYMOUS0(type,__LINE__)
例:ANONYMOUS(staticint);即:staticint_anonymous70;70表示该行行号;
第一层:ANONYMOUS(staticint);-->__ANONYMOUS0(staticint,__LINE__);
第二层:-->___ANONYMOUS1(staticint,_anonymous,70);
第三层:-->staticint_anonymous70;
即每次只能解开当前层的宏,所以__LINE__在第二层才能被解开;
2、填充结构
#defineFILL(a){a,#a}
enumIDD{OPEN,CLOSE};
typedefstructMSG{
IDDid;
constchar*msg;
}MSG;
MSG_msg[]={FILL(OPEN),FILL(CLOSE)};
相当于:
MSG_msg[]={{OPEN,"OPEN"},
{CLOSE,"CLOSE"}};
3、记录文件名
#define_GET_FILE_NAME(f)#f
#defineGET_FILE_NAME(f)_GET_FILE_NAME(f)
staticcharFILE_NAME[]=GET_FILE_NAME(__FILE__);
4、得到一个数值类型所对应的字符串缓冲大小
#include<stdio.h>
#defineINT_MAX0x7fffffff
#define_TYPE_BUF_SIZE(type)sizeof#type
#defineTYPE_BUF_SIZE(type)_TYPE_BUF_SIZE(type)
intmain()
{
printf("%d\n",TYPE_BUF_SIZE(INT_MAX));//11
return0;
}
相当于:
TYPE_BUF_SIZE(INT_MAX)—>_TYPE_BUF_SIZE(0x7fffffff)—>sizeof"0x7fffffff";