重新定义OUTSCREEN宏如下: #define OUTSCREEN(msg, ...) printf(msg, ##__VA_ARGS__) 当可变参数的个数为0时,这里的##起到把前面多余的","去掉,实际上变成了printf(msg),这样编译就能通过了。 ,__VA_ARGS__这个宏实在不利于记忆,gcc对此做了扩展,另一种可接受的定义方法为: #define OUTSCREEN(msg,...
beyes@linux-beyes:~/C/micro> ./mic.exe hello world 编译通过,并正常输出。上面的代码,在 fprintf() 中的 args 前面加了两个 # 号 ##。 ##号的作用是: 如果可变参数部分( args...) 被忽略或为空,那么 "##" 操作会使预处理器 (preprocessor) 去掉它前面的那个逗号。如果在调用宏时,确实提供了一...
第一个宏中由于没有对变参起名,我们用默认的宏__VA_ARGS__来替代它。第二个宏中,我们显式地命名变参为args,那么我们在宏定义中就可以用args来代指变参了。同C语言的stdcall一样,变参必须作为参数表的最有一项出现。当上面的宏中我们只能提供第一个参数templt时,C标准要求我们必须写成: myprintf(templt,);...
有一个记录日志的函数,想用宏定义进行包装,简化调用方法,但是xlc报如下的错误: void _log(const int level, char* file, int line, const char* fmt, ...){ va_list ap; int count; time_t t; struct tm* st; char str_time[255]; memset(str_time, 0x00, sizeof(str_time)); time(&t); ...
这里很清楚了,真正的函数是logger_action,两个宏分别包装了一下。这里: 1. 在宏定义中,使用__VA_ARGS__来表示可变参数,前面用...即可。如果可变参数为空,那么,理论上就会多产生一个逗号导致编译失败 (format参数后面多一个逗号),此时,__VA_ARGS__会自动消除多余的逗号。这是VC编译器的动作,如果是GNU的编译...
#defineFM_LOG_DEBUG(x...) log_write(LOG_DEBUG, __FILE__, __LINE__, ##x)
于C标准库的语言,printf、scanf、sscanf、sprintf、sscanf入输出函数,參数都是可变的。在调试程序时。我们可能希望定义一个參数可变的输出函数来记录日志,那么用可变參数的宏是一个不错的选择。 在C99中规定宏也能够像函数一样带可变的參数,如: #define LOG(format, ...) fprintf(stdout, format, __VA_ARGS__...
C语言中宏定义之##用于可变参数 C语⾔中宏定义之##⽤于可变参数 GCC ⽀持复杂的宏,它使⽤⼀种不同的语法,使你可以给可变参数⼀个名字,如同其它参数⼀样,⽐如:引⽤ #define debug(format, args...) fprintf(stderr, format, args)这种定义可读性更强,也更容易描述。完整测试代码:引...
C语言 如何在宏定义中使用可变参数 faker 26452132 发布于 2013-03-06 有一个记录日志的函数,想用宏定义进行包装,简化调用方法,但是xlc报如下的错误: void _log(const int level, char* file, int line, const char* fmt, ...){ va_list ap; int count; time_t t; struct tm* st; char str_...
这里很清楚了,真正的函数是logger_action,两个宏分别包装了一下。这里: 1. 在宏定义中,使用__VA_ARGS__来表示可变参数,前面用...即可。如果可变参数为空,那么,理论上就会多产生一个逗号导致编译失败 (format参数后面多一个逗号),此时,__VA_ARGS__会自动消除多余的逗号。这是VC编译器的动作,如果是GNU的编译...