gnu printf可变参数宏

可变参数的宏

标准C只支持可变参数的函数,意味着函数的参数可以是不固定的

例如printf()函数的原型是int printf(const char *format [,argument]...)

而在GNU C中,宏也可以接受可变数目的参数,例如

#define pr_debug(fmt,arg...) printk(fmt,##arg)

这里arg表示其余的参数可以是零个或多个,这些参数以及参数之间的逗号构成arg的值,在宏扩展时替换arg ,例如

pr_debug("%s:%d",filename,line);被扩展为printk("%s:%d",filename,line);

使用##的原因是为了处理arg不代表任何参数的情况,这时候,前面的逗号就变得多余了。

使用##之后,GNU C预处理器会丢弃前面的逗号,这样代码pr_debug("success!/n") 会被正确扩展为 printk("success!/n")

而不是 printk("success!/n",);

时间: 2024-08-07 20:52:26

gnu printf可变参数宏的相关文章

可变参数宏__VA_ARGS__

在 GNU C 中,宏可以接受可变数目的参数,就象函数一样,例如: #define pr_debug(fmt,arg...) \ printk(KERN_DEBUG fmt,##arg) 用可变参数宏(variadic macros)传递可变参数表 你可能很熟悉在函数中使用可变参数表,如: void printf(const char* format, -); 直到最近,可变参数表还是只能应用在真正的函数中,不能使用在宏中. C99编译器标准终于改变了这种局面,它允许你可以定义可变参数宏(var

嵌入式C语言自我修养 12:有一种宏,叫可变参数宏

12.1 什么是可变参数宏 在上面的教程中,我们学会了变参函数的定义和使用,基本套路就是使用 va_list.va_start.va_end 等宏,去解析那些可变参数列表我们找到这些参数的存储地址后,就可以对这些参数进行处理了:要么自己动手,自己处理:要么继续调用其它函来处理. void print_num(int count, ...) { va_list args; va_start(args,count); for(int i = 0; i < count; i++) { printf(&qu

预处理程序之可变参数宏定义

printf()和fprintf()这些输出函数的参数是可变的,在调试程序时,你可能希望定义自己的参数可变的输出函数, 那么可变参数宏会是一个选择. C99中规定宏可以像函数一样带有可变参数,比如 #define LOG(format, ...) fprintf(stdout, format, __VA_ARGS__) 其中,...表示参数可变,__VA_ARGS__在预处理中为实际的参数集所替换 GCC中同时支持如下的形式 #define LOG(format, args...) fprint

自定义print macro,两对括号,单参数macro、指定参数macro、可变参数宏

v1--单参数宏 #define DRV_DEBUG 1 #if DRV_DEBUG #define DRV_PRINT(x) printf(x) #else #define DRV_PRINT(x) #endif 这个版本的DRV_PRINT(x)只能输出单变量--纯字符串 void foo() { DRV_PRINT("Driver Initialize Success!"); } 不需要打印调试信息时,更改DRV_DEBUG宏定义 #define DRV_DEBUG 0 当然也可

__VA_ARGS__可变参数宏

#define qWiFiDebug(format, ...) qDebug("[WiFi] "format" File:%s, Line:%d, Function:%s", ##__VA_ARGS__, __FILE__, __LINE__ , __FUNCTION__); __VA_ARGS__ 是一个可变参数的宏,很少人知道这个宏,这个可变参数的宏是新的C99规范中新增的,目前似乎只有gcc支持(VC6.0的编译器不支持).宏前面加上##的作用在于,当可变参数

可变参数宏(DEBUG)

之前一直是到处写printf来打印调试信息,不需要是还得一个一个注释掉.之后上网查询发现有很多方法来进行DEBUG打印,参数可变而且方便一次性开关. #define DEBUG(fmt,...)    printf (fmt,__VA_ARGS__)        这里的"-"指的是可变参数. int main() { DEBUG("hello %d",10); return 0; } 有时候,有个模块有输出信息,错误信息等.如果想单独打开某一部分,可以如此设计:

可变参数宏...和__VA_ARGS__

__VA_ARGS__ 是一个可变参数的宏,很少人知道这个宏,这个可变参数的宏是新的C99规范中新增的,目前似乎只有gcc支持(VC6.0的编译器不支持).实现思想就是宏定义中参数列表的最后一个参数为省略号(也就是三个点).这样预定义宏_ _VA_ARGS_ _就可以被用在替换部分中,替换省略号所代表的字符串.比如:#define PR(...) printf(__VA_ARGS__)int main(){    int wt=1,sp=2;    PR("hello\n");   

Printf可变参数使用

参考文档: http://bbs.csdn.net/topics/70288067 Owed by: 春夜喜雨 http://blog.csdn.net/chunyexiyu 转载请标明来源 本文的二个重点: 1. 可变参数实际上通过首个参数的地址来获取其它参数的地址,因为是顺序存储传过来的 1.      可变参数为了处理方便,所有的浮点型都是按照double型压栈. 因此,像printf采用的可变参数,它直接使用%f显示double型,不需要管float型. 关注printf的精度,需要先关

glibc 中确定宏参数个数的宏__SYSCALL_NARGS 及 可变参数宏__VA_ARGS__

读 glibc 中 关于 socket 系统调用实现的部分,然后看到了这里,写在这里做份一份笔记. #define __SYSCALL_NARGS_X(a,b,c,d,e,f,g,h,n,...) n #define __SYSCALL_NARGS(...) \ __SYSCALL_NARGS_X (__VA_ARGS__,7,6,5,4,3,2,1,0,) #define __SYSCALL_CONCAT_X(a,b) a##b #define __SYSCALL_CONCAT(a,b) __