不清不楚之C语言中##__VA_ARGS__与__VA_ARGS__

d4b57da827a61732536805227ea4e64f.gif

正文


大家好,我是bug菌~

最近在开发过程中又玩起了C语言的可变参数,在资源受限的MCU平台上,一般不太建议使用可变参数或者相应标准库函数如printf等,以免编译进去后导致程序代码段瞬间变大很多,当然有些简化版本的lib,不过也相当废资源,不过现在MCU的性能越来越卷,大部分项目都是资源过剩。

不过话说回来,C语言的可变参数用起来还挺顺手,像嵌入式经常打印的日志,为了更好的可移植性通常会进行封装,今天就不再赘述可变参数的语法了,大家感兴趣可以翻阅公众号往期文章,今天bug菌仅聊聊##__VA_ARGS__与__VA_ARGS__这对可变参数宏,相信大家在日常的编程中接触得倒不多,不过在大型开源软件中还是屡有见到,那么下面带大家分析分析:

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进阶专辑 9333a385ddd84652d59416f085d1c2ed.gif

☞  嵌入式C语言进阶专辑 dc85111a786d8258a389e4eb681bed61.gif

☞  “bug说”专辑 8eb62fdd55ac91a7374391c67a835869.gif

☞ 专辑|Linux应用程序编程大全

☞ 专辑|学点网络知识

☞ 专辑|手撕C语言

☞ 专辑|手撕C++语言

☞ 专辑|经验分享

☞ 专辑|电能控制技术

☞ 专辑 | 从单片机到Linux

e5899ad9b57d6efff0739e867fcf96a2.gif

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值