C语言中##的用法
今天看linux操作系统源码是有这么一段:
#define _syscall0(type,name) \
type name(void) \
{ \
long __res; \
__asm__ volatile ( "int $0x80" \ // 调用系统中断0x80。
:"=a" (__res) \ // 返回
值??eax(__res)。
:"" (__NR_
##name)); \ // 输入为系统中断调用号__NR_name。 if (__res >;= 0) \ // 如果返回值>;=0,则直接返
回该值。
return (type) __res; errno = -__res; \ // 否则置出错号,并返回-1。
return -1;}
其中有一个地方出现了两个‘#’号不明白什么意思,网上找到了一段论坛:
宏中"#"和"##"的用法
一、一般用法
我们使用#把宏参数变为一个字符串,用##把两个宏参数贴合在一起.
用法:
#include;
#include;
usingnamespacestd;
#defineSTR(s)
#s
#defineCONS(a,b)
int(a##e##b)
intmain()
{
printf(STR(vck));
//输出字符串"vck"
printf("%d
",CONS(2,3));
//2e3输出:2000
return0;
}
二、当宏参数是另一个宏的时候
需要注意的是凡宏定义里有用'#'或'##'的地方宏参数是不会再展开.
1,非'#'和'##'的情况
#defineTOW
(2)
#defineMUL(a,b)(a*b)
printf("%d*%d=%d
",TOW,TOW,MUL(TOW,TOW));
这行的宏会被展开为:
printf("%d*%d=%d
",(2),(2),((2)*(2)));
MUL里的参数TOW会被展开为(2). 2,当有'#'或'##'的时候
#defineA
(2)
#defineSTR(s)
#s
#defineCONS(a,b)
int(a##e##b)
printf("intmax:%s
",
STR(INT_MAX));
//INT_MAX#include;
这行会被展开为:
printf("intmax:%s
","INT_MAX"); printf("%s
",CONS(A,A));
//compileerror
这一行则是:
printf("%s
",int(AeA));
INT_MAX和A都不会再被展开,然而解决这个问题的方法很简单.加多一层中间转换宏.
加这层宏的用意是把所有宏的参数在这层里全部展开,那么在转换宏里的那一个宏(_STR)就能得到正确的宏参数. #defineA
(2)
#define_STR(s)
#s
#defineSTR(s)
_STR(s)
//转换宏
#define_CONS(a,b)
int(a##e##b)
#defineCONS(a,b)
_CONS(a,b)
//转换宏
printf("intmax:%s
",STR(INT_MAX));
//INT_MAX,int型的最大值,为一个变量#include;
输出为:intmax:0x7fffffff
STR(INT_MAX)-->;
_STR(0x7fffffff)然后再转换成字符串;printf("%d
",CONS(A,A));
输出为:200
CONS(A,A)
-->;
_CONS((2),(2))
-->;int((2)e(2))
三、'#'和'##'的一些应用特例
1、合并匿名变量名
#define
___ANONYMOUS1(type,var,line)
type
var##line
#define
__ANONYMOUS0(type,line)
___ANONYMOUS1(type,_anonymous,line) #define
ANONYMOUS(type)
__ANONYMOUS0(type,__LINE__)
例:ANONYMOUS(staticint);
即:staticint_anonymous70;
70表示该行行号;
第一层:ANONYMOUS(staticint);
-->;
__ANONYMOUS0(staticint,__LINE__);
第二层:
-->;
___ANONYMOUS1(staticint,_anonymous,70);
第三层:
-->;
staticint
_anonymous70;
即每次只能解开当前层的宏,所以__LINE__在第二层才能被解开;
2、填充结构
#define
FILL(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
#define
GET_FILE_NAME(f)
_GET_FILE_NAME(f)
staticchar
FILE_NAME[]=GET_FILE_NAME(__FILE__);
4、得到一个数值类型所对应的字符串缓冲大小#define
_TYPE_BUF_SIZE(type)
sizeof#type
#define
TYPE_BUF_SIZE(type)
_TYPE_BUF_SIZE(type)
char
buf[TYPE_BUF_SIZE(INT_MAX)];
-->;
char
buf[_TYPE_BUF_SIZE(0x7fffffff)];
-->;
char
buf[sizeof"0x7fffffff"]; 这里相当于:
char
buf[11];
自己在linux下编写了一段程序:
#include;
#define transform 1##2##3
int main()
{
int result=transform*transform;
printf("the num of result
is : %d",result);
return 0;
}
函数输出的结果是15129(=123*123)--得出结论是:##的作用之一是将前后两个宏参数连在一起!