正文
1
__VA_ARGS__介绍
__VA_ARGS__ 是C语言中的一个预定义宏,用于处理可变数量的参数列表。通常用在宏定义中,以便宏能够接受不定数量的参数,并将它们作为整体处理。
在C语言中,使用函数可以接受可变数量的参数,例如printf和fprintf。然而,在宏定义中,参数数量通常是固定的。为了能够定义可以处理不同数量参数的宏,C99标准引入了__VA_ARGS__。下面的例子也都是在C99标准下编译运行。
__VA_ARGS__表示所有在宏调用中传递的额外参数。它可以放在宏定义的参数列表的末尾,用于接收任意数量的额外参数,比如:
#define DEBUG_LOG(fmt, ...) printf(fmt, __VA_ARGS__)
解析:
DEBUG_LOG 是一个宏,接受至少一个参数 fmt(格式化字符串),后面可以是任意数量的参数。
__VA_ARGS__ 表示可变参数列表,在宏展开时会被替换为传递给 DEBUG_LOG 宏的所有实际参数。
示例:
#define DEBUG_LOG(fmt, ...) \
printf("[%s:%d] " fmt "\n", __FILE__, __LINE__, __VA_ARGS__)
DEBUG_LOG("Hello, %s! The answer is %d\n", "world", 42);
在这个调用中,"Hello, %s! The answer is %d\n" 是格式化字符串fmt,"world" 和 42 是额外的参数。这些参数会被依次传递给 printf 函数。__VA_ARGS__ 必须总是与宏定义中的省略号 ... 一起使用。省略号...用于指示宏可以接受可变数量的参数。在宏定义中,__VA_ARGS__ 可以单独使用(如果没有额外参数时),也可以与其他参数一起使用。
2
##在前面有啥用?
大家在了解__VA_ARGS__时,一定会看到有些地方在该宏定义前使用 ## 运算符来处理可变参数,如:
#define DEBUG_LOG(fmt, ...) \
printf("[%s:%d] " fmt "\n", __FILE__, __LINE__, ##__VA_ARGS__)
其中这里的##运算符主要是用于连接左侧的符号(通常是逗号)和右侧的参数,从而确保宏展开时语法正确。
对于如下使用可变参数:
DEBUG_LOG("Value of x: %d", 42);
__VA_ARGS__与##__VA_ARGS__是没有太大区别的,且都能编译通过,打印输出相同的结果。
然而当可变参数为空时,如下:
DEBUG_LOG("Program starting...");
在C99编译器下,无##修饰的宏定义DEBUG_LOG 则会编译失败,而存在##修饰的宏##__VA_ARGS__ 处理为空的可变参数列表,防止在宏展开时出现不必要的逗号,从而使得编译通过。
最后
好了,今天就跟大家分享这么多了,如果你觉得有所收获,一定记得点个赞~
bug菌唯一、永久、免费分享嵌入式技术知识平台~
推荐专辑 点击蓝色字体即可跳转
☞ MCU进阶专辑
☞ 专辑|手撕C语言
☞ 专辑|经验分享