c语言#、##、 ## __VA_ARGS__ 的用法
在看linux内核kernel.h里面看到这样一个语句:
#define pr_err(fmt, ...) \
eprintf(0, pr_fmt(fmt), ##__VA_ARGS__)
看不懂,于是百度了一下,感谢度娘和博主!
转载于:http://www.cnblogs.com/alexshi/archive/2012/03/09/2388453.html
http://www.cnblogs.com/zhujudah/archive/2012/03/22/2411240.html
首先,#define 是常见的预编译命令,但是假如#放在其它地方用有些巧妙的地方。
1,先来看一个例子:
#include<stdio.h> #include <stdlib.h> #define Func1(x) printf("the square of " #x " is %d.\n",(x)*(x)) int main(void) { int aa=30; Func1(aa); Func1(30); system("pause"); return 0; }
输出:
the square of aa is 900.
the square of 30 is 900.
分析》:#用在预编译语句里面可以把预编译函数的变量直接格式成字符串;注意,不能直接在其它非预编译函数直接使用#aa的形式,假如main函数里面出现printf("the square of " #x " is %d.\n",(x)*(x))是不能通过编译的.
2,
#include<stdio.h> #include <stdlib.h> #define Func3(a) printf("the square of " #a " is %d.\n",b##a) int main(void) { int m=30; int bm=900; Func3(m); //展开后相当于 printf("the square of m is %d.\n",bm); system("pause"); return 0; }
输出:
the square of m is 900.
分析》:## 是宏连接符,作变量链接,Func(a)里面有b##a,也就是说直接连接成b‘a’,Func3(m)对应bm,由于bm在main里面有定义,所以可以打印出来。
3,##__VA_ARGS__这里的‘##’有特殊作用,
__VA_ARGS__是可变参数宏,用法如下:
#define Debug(...) printf(__VA_ARGS__)
使用的时候只需要:
Debug(
"Y = %d\n"
, y);
此时编译器会自动替换成printf("Y = %d\n"
, y
");
对于##__VA_ARGS__的‘##’符号的用法,
例如:#define debug(format, ...) fprintf (stderr, format, ## __VA_ARGS__)
假如可变参数宏为空的时候,”“##”的作用就是让编译器忽略前面一个逗号,不然编译器会报错。