GNU C语言 宏定义 #args ##args

文章转自:http://blog.chinaunix.net/uid-21830881-id-1813972.html

如果大家看到,下记代码,一些人一定会有一些疑问

#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语句的位置,看其被预编译替换成了什么?
这样就更好理解了。


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值