文档库 最新最全的文档下载
当前位置:文档库 › C语言中##的用法

C语言中##的用法

C语言中##的用法
C语言中##的用法

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)--得出结论是:##的作用之一是将前后两个宏参数连在一起!

相关文档