【预处理】——获取可变参数宏的参数数量

这篇具有很好参考价值的文章主要介绍了【预处理】——获取可变参数宏的参数数量。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

功能说明

用于获取可变参数宏实际传递了多少个参数。

  • COUNT_ARGS(1, 2, 3),填入了 3 个参数,返回值就是 3
  • COUNT_ARGS("Hello", 'a', 3.14, 4),填入了 4 个 参数,返回值就是 4
  • COUNT_ARGS(1),我们填入了 1 个参数,返回值就是 1

实现

#define __COUNT_ARGS(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18, _19, _20, N, ...) N
#define COUNT_ARGS(...) __COUNT_ARGS(, ##__VA_ARGS__, 20, 19, 18, 17, 16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0)
  1. __COUNT_ARGS 宏定义了一个带有多个参数的宏,其中 _0 到 _20 是占位符参数, N 表示参数个数。
  2. __COUNT_ARGS 宏使用了变参宏的特性,通过 ## 将参数序列转换为逗号分隔的参数列表。
  3. COUNT_ARGS 宏定义了一个变参宏,它使用 __COUNT_ARGS 宏来计算参数个数。
  4. COUNT_ARGS 宏通过添加一个空参数 (,) 来处理没有参数的情况,避免编译错误。
  5. COUNT_ARGS 宏最多可以接受 20 个参数,如果超过 20 个参数,则只会计算前 20 个参数的个数。

... 的作用

... 是一个可变参数宏的语法,它表示可以接受任意数量的参数。在宏定义中,... 表示参数列表的结束,可以在宏的定义中使用这些参数。

__VA_ARGS__ 的作用

  • __VA_ARGS__ 是一个特殊的宏,它表示可变参数的占位符。在宏定义中, __VA_ARGS__ 会被替换为传递给宏的实际参数。它可以用于将可变参数传递给其他宏或函数。

##__VA_ARGS__ 的作用

##__VA_ARGS__ 是在可变参数宏中使用的一个特殊语法。它的作用是在宏展开时,将可变参数的逗号连接符去除,以避免出现多余的逗号。这在某些情况下非常有用,特别是当宏的参数列表为空时。

当我们没有参数向 COUNT_ARGS 传递时,__VA_ARGS__ 的值为空,, ##__VA_ARGS__ 这部分会被删除。这里是使用了 ## 的语法,当 __VA_ARGS__ 为空字符串时,会连同最开始的 , 被一并删除了。

解析

#define __COUNT_ARGS(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18, _19, _20, N, ...) N

这个宏要求至少传递 22 个参数,返回值就是这第 22 个参数。

如果超过第 22 个的参数,会被 … 给消化,并且返回第 22 个参数。

其实该宏的本质是先用 20, 19, ... 1, 0 占位,每多加一个参数,最右边的数就会被挤掉。

增加一个参数,0 就被挤掉,返回第 22 个参数就是 1
增加两个参数,0 和 1就被挤掉,返回第 22 个参数就是 2
以此类推

COUNT_ARGS(2, 4, 5)

COUNT_ARGS(2, 4, 5) 展开后就变为

__COUNT_ARGS(, 2, 4, 5, 20, 19, 18, 17, 16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0)

传递了 25 个参数给 __COUNT_ARGS ,接下来我们再与 __COUNT_ARGS 里的 形参 进行对应:

__COUNT_ARGS 宏的作用是返回实参的第 22 个参数,实际 __COUNT_ARGS 传递了 25 个参数 ,所以该宏只返回第 22 个参数即 3

没有参数 COUNT_ARGS()

COUNT_ARGS() 展开后就变为

__COUNT_ARGS(, 20, 19, 18, 17, 16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0)

有 22 个参数传递给 __COUNT_ARGS ,然后传递的参数与 __COUNT_ARGS 里的形参进行一一对应:
__COUNT_ARGS 宏的作用是返回实参的第 22 个参数,实际 __COUNT_ARGS 传递了 22 个参数 ,所以该宏只返回第 22 个参数即 0

参数大于 22 个

另外要注意传入的参数不能超过 22 个。如果传入的参数大于 22 个,那么这个宏将返回第 22 个参数的参数值。

例如

COUNT_ARGS(c)

宏展开后就是

(, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 46, 76, 20, 19, 18, 17, 16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0)

传递了 44 个参数给 __COUNT_ARGS ,接下来我们再与 __COUNT_ARGS 里的 形参 进行对应:

__COUNT_ARGS 宏的作用是返回实参的第 22 个参数,实际 __COUNT_ARGS 传递了 44 个参数 ,所以该宏只返回第 22 个参数即 46

所以当参数超过 22 个之后,不管参数的数量是多少,N 对应的永远是第 22 个参数的值。

示例

#include <stdio.h>

#define __COUNT_ARGS(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18, _19, _20, N, ...) N
#define COUNT_ARGS(...) __COUNT_ARGS(, ##__VA_ARGS__, 20, 19, 18, 17, 16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0)

int main(int argc, char *argv[])
{
    int count1 = COUNT_ARGS();                                                                              // count1 = 0
    int count2 = COUNT_ARGS(1, 2, 3);                                                                       // count2 = 3
    int count3 = COUNT_ARGS(1, 2, 3, 4, 5, 6, 7);                                                           // count3 = 7
    int count4 = COUNT_ARGS("Hello", 'a', 3.14);                                                            // count4 = 3
    int count5 = COUNT_ARGS(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20);         // count5 = 20
    int count6 = COUNT_ARGS(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 46, 76); // count6 = 20

    printf("count1 = %d\n", count1);
    printf("count2 = %d\n", count2);
    printf("count3 = %d\n", count3);
    printf("count4 = %d\n", count4);
    printf("count5 = %d\n", count5);
    printf("count6 = %d\n", count6);

    return 0;
}

结果打印文章来源地址https://www.toymoban.com/news/detail-612999.html

count1 = 0
count2 = 3
count3 = 7
count4 = 3
count5 = 20
count6 = 46

到了这里,关于【预处理】——获取可变参数宏的参数数量的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • yolov2检测网数据集获取与预处理_采集健康和非健康猫狗数据

    阿里云天池数据集-cat-dog 因为开源数据库中没有非健康猫狗相关的,所以需要自己下载非健康猫狗数据,并制作数据集。 下面是用于爬取非健康猫狗数据的爬虫代码: 使用图片去重/相似图片清理利器 软件清除重复的图片数据。 使用ffmpeg将救助视频文件按照一秒截取一张

    2024年02月14日
    浏览(62)
  • matlab数据的获取、预处理、统计、可视化、降维 | 《matlab数学建模方法与实践(第三版)》学习笔记

    一、数据的获取 1.1 从Excel中获取 使用readtable() 使用xlsread()——xlswrite() 1.2  从TXT中获取 使用load() 使用textread() 使用fopen() fread() fclose()  使用fprintf()写入信息到txt  1.3 从图片中获取 使用imread  1.4 从视频获取  使用视觉工具箱中的VideoFileReader  二、数据的预处理 2.1 缺失值处

    2024年01月19日
    浏览(55)
  • 基于Python的海量豆瓣电影、数据获取、数据预处理、数据分析、可视化、大屏设计项目(含数据库)

    项目介绍 有需要本项目的代码或文档以及全部资源,或者部署调试可以私信博主!!!!!!!!!! 本文基于Python的网络爬虫手段对豆瓣电影网站进行数据的抓取,通过合理的分析豆瓣网站的网页结构,并设计出规则来获取电影数据的JSON数据包,采用正态分布的延时措施

    2024年02月12日
    浏览(41)
  • C语言-程序环境和预处理(2)--带副作用的宏参数,宏与函数的对比,#undef,条件编译,文件包含

    上一篇文章–《C语言-程序环境和预处理(1)》讲述了程序的翻译环境和执行环境,编译、连接,预定义符号,#define,#符号和##符号的相关知识。 链接: 《C语言-程序环境和预处理(1)》 本篇文章,讲述带副作用的宏参数,宏与函数的对比,#undef,条件编译,文件包含的相

    2024年02月08日
    浏览(48)
  • 【C语言】程序环境和预处理|预处理详解|定义宏(下)

    主页:114514的代码大冒 qq:2188956112(欢迎小伙伴呀hi✿(。◕ᴗ◕。)✿ ) Gitee:庄嘉豪 (zhuang-jiahaoxxx) - Gitee.com 文章目录 目录 文章目录 前言 2.5带副作用的宏参数 2.6宏和函数的对比 3#undef ​编辑 4 命令行定义 5 条件编译 6 文件包含 总结 咱们书接上回 2.5带副作用的宏参数 先来

    2024年01月17日
    浏览(44)
  • 数据采集与预处理01: 项目1 数据采集与预处理准备

    数据采集:足够的数据量是企业大数据战略建设的基础,因此数据采集成为大数据分析的前站。数据采集是大数据价值挖掘中重要的一环,其后的分析挖掘都建立在数据采集的基础上。大数据技术的意义确实不在于掌握规模庞大的数据信息,而在于对这些数据进行智能处理,

    2024年01月25日
    浏览(45)
  • C语言——程序环境和预处理(再也不用担心会忘记预处理的知识)

    先简单了解一下程序环境,然后详细总结翻译环境里的编译和链接,然后在总结编译预处理。 在 ANSI C 的任何一种实现中,存在两个不同的环境 翻译环境:这个环境中源代码被转换为可执行的机器指令。 执行环境:执行二进制代码。 计算机如何执行二进制指令? 我们写的C语

    2024年02月09日
    浏览(43)
  • 图像预处理算法————灰度化处理

    图像预处理算法适合在FPGA上完成,原理简单且需要快速处理,通常有灰度化、中值、均值滤波等,以及颜色空间转换算法。 灰度图像是一种特殊的彩色图像(R=G=B的彩色图像) 只有一种颜色分量,单通道的0-255 方法:一般有分量法、最大值法、平均值法、加权平均法四种方

    2024年01月17日
    浏览(39)
  • 昇腾CANN DVPP硬件加速训练数据预处理,友好解决Host CPU预处理瓶

    本文分享自华为云社区《昇腾CANN 7.0 黑科技:DVPP硬件加速训练数据预处理,友好解决Host CPU预处理瓶颈》,作者: 昇腾CANN 。 随着人工智能的快速发展,越来越多的应用场景需要使用机器学习和深度学习模型。AI网络模型的训练一般分成两个关键部分,一个是训练数据预处理

    2024年02月05日
    浏览(37)
  • 大数据采集技术与预处理学习一:大数据概念、数据预处理、网络数据采集

    目录 大数据概念: 1.数据采集过程中会采集哪些类型的数据? 2.非结构化数据采集的特点是什么? 3.请阐述传统的数据采集与大数据采集的区别? ​​​​​​​ ​​​​​​​4.大数据采集的数据源有哪些?针对不同的数据源,我们可以采用哪些不同的方法和工具? 数据

    2024年01月25日
    浏览(39)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包