如果大家看到,下记代码,一些人一定会有一些疑问
#define DBG_OUTPUT(fmt, args...) printf("CK File[%s:%s(%d)]:" fmt "\n", __FILE__, __FUNCTION__, __LINE__, ##args)
|
args...是什么?
##args 是什么?
如何应用?
如何传递?
..........
①args...
GCC编译器中的CPP预编译器,是支持这种写法的,args... 比 args,... 的写法可读性较好。
含义:应该是DBG_OUTPUT的参数,第一个传给fmt, 第二个开始传给args...可为多个。
②##args
##args的意思,就是把args...中的多个参数,串连起来。
另外,如果写成 #fmt的话,就是把fmt传进来的内容以字符串形式输出。(下面例子中会说明)
#include <stdio.h>
#define DBG_OUTPUT(fmt,args...) printf("CK File[%s:%s(%d)]:" fmt "\n", __FILE__, __FUNCTION__, __LINE__, ##args)
int
main(int argc,char **argv){
char j;
unsigned char k;
j = 0xF1;
k = 0xF1;
DBG_OUTPUT("j[%d]k[%d]", j, k);
/* printf("CK File[%s:%s(%d)]:" "j[%d]k[%d]" "\n", __FILE__, __FUNCTION__, __LINE__, j, k) */
return 0;
} /* test.c */
|
可以看出来么?
DBG_OUTPUT("j[%d]k[%d]", j, k); 预编译后实际内容就是其下行的注释中的内容。
"j[%d]k[%d]"作为一个参数,传递给了fmt。(包含 ""双引号)
j, k作为两个参数传给args... , 在printf语句中,使用的是##args,所以这两个参数,被串联放在了printf语句中。
下面说明#fmt(就是一个#符号是什么意思)
#include <stdio.h>
#define DBG_OUTPUT(fmt,args...) printf("CK File[%s:%s(%d)]:" #fmt "\n", __FILE__, __FUNCTION__, __LINE__, ##args)
int
main(int argc,char **argv){
char j;
unsigned char k;
j = 0xF1;
k = 0xF1;
DBG_OUTPUT(j[%d]k[%d], j, k);
/* printf("CK File[%s:%s(%d)]:" "j[%d]k[%d]" "\n", __FILE__, __FUNCTION__, __LINE__, j, k) */
return 0;
} /* test.c */
|
与前一例代码有 2 点不同。
①DBG_OUTPUT的宏定义的printf语句中,将fmt换成了#fmt
②main()函数中的DBG_OUTPUT的语句中,""双引号,去掉了。
也就是说,j[%d]k[%d]作为一个参数传递给了fmt,在printf中使用的是#fmt,所以j[%d]k[%d]作为字符串输出,相当于"j[%d]k[%d]"。
所以,两段例代码的注释部分是完全一样的。输出结果当然也一样。
注:
GCC的option -E 为向标准输入输出中,输出预编译结果。
所以,通过命令
$ gcc -E test.c >& test.i
(生成预编译结果,保存在test.i的文本文件中)
再打开,test.i文件,在最下面找到原DBG_OUTPUT语句的位置,看其被预编译替换成了什么?
这样就更好理解了。
另可参考:可变参数宏