linux c程序加args,C/C++可变参数,“## __VA_ARGS__”宏的介绍和使用

在阅读代码的时候,在一个宏定义语句中,发现了个之前未曾见过的编译器预定义宏:“__VA_ARGS__”。当时,从代码语句中推测它代表宏参数:“…”(本文称之为省略号),依稀记得printf函数声明中有使用这个省略号,大概的意思是表示可变化的参数,但未深入了解。

在网上看了相关文章的介绍,主要涉及了C/C++函数中可变化参数的基础知识,并延伸到宏定义中的可变参数。借这一次的学习,算是对可变化参数有了比较详细的了解,尤其是解开了一直萦绕在头脑中printf函数声明中这个省略号的疑惑。

为更好了解C/C++中可变参数的知识,我从网上摘录了两篇文章,算是自己的一个总结。本篇主要是关于“## __VA_ARGS__”宏的介绍和使用。

在GNU C中,宏可以接受可变数目的参数,就象函数一样,例如:

用可变参数宏(variadic macros)传递可变参数表

你可能很熟悉在函数中使用可变参数表,如:

直到最近,可变参数表还是只能应用在真正的函数中,不能使用在宏中。

C99编译器标准终于改变了这种局面,它允许你可以定义可变参数宏(variadic macros),这样你就可以使用拥有可以变化的参数表的宏。可变参数宏就像下面这个样子:

缺省号代表一个可以变化的参数表。使用保留名 __VA_ARGS__ 把参数传递给宏。当宏的调用展开时,实际的参数就传递给 printf()了。例如:

而处理器会把宏的调用替换成:

因为debug()是一个可变参数宏,你能在每一次调用中传递不同数目的参数:

可变参数宏不被ANSI/ISO C++ 所正式支持。因此,你应当检查你的编译器,看它是否支持这项技术。

用GCC和C99的可变参数宏, 更方便地打印调试信息

gcc的预处理提供的可变参数宏定义真是好用:

如此定义之后,代码中就可以用dbgprint了,例如dbgprint("%s", __FILE__);

下面是C99的方法:

新的C99规范支持了可变参数的宏

具体使用如下:

以下内容为程序代码:

但现在似乎只有gcc才支持。

可变参数的宏里的'##'操作说明带有可变参数的宏(Macros with a Variable Number of Arguments)

在1999年版本的ISO C 标准中,宏可以象函数一样,定义时可以带有可变参数。宏的语法和函数的语法类似。下面有个例子:

这里,'...'指可变参数。这类宏在被调用时,它(这里指'...')被表示成零个或多个符号,包括里面的逗号,一直到到右括弧结束为止。当被调用时,在宏体(macro body)中,那些符号序列集合将代替里面的__VA_ARGS__标识符。更多的信息可以参考CPP手册。

GCC始终支持复杂的宏,它使用一种不同的语法从而可以使你可以给可变参数一个名字,如同其它参数一样。例如下面的例子:

这和上面举的那个ISO C定义的宏例子是完全一样的,但是这么写可读性更强并且更容易进行描述。

GNU CPP还有两种更复杂的宏扩展,支持上面两种格式的定义格式。

在标准C里,你不能省略可变参数,但是你却可以给它传递一个空的参数。例如,下面的宏调用在ISO C里是非法的,因为字符串后面没有逗号:

debug ("A message")

GNU CPP在这种情况下可以让你完全的忽略可变参数。在上面的例子中,编译器仍然会有问题(complain),因为宏展开后,里面的字符串后面会有个多余的逗号。

为了解决这个问题,CPP使用一个特殊的'##'操作。书写格式为:

这里,如果可变参数被忽略或为空,'##'操作将使预处理器(preprocessor)去除掉它前面的那个逗号。如果你在宏调用时,确实提供了一些可变参数,GNU CPP也会工作正常,它会把这些可变参数放到逗号的后面。象其它的pasted macro参数一样,这些参数不是宏的扩展。

##还可以起到替换作用

如:

这里将会把IName变成实际数据.

怎样写参数个数可变的宏

一种流行的技巧是用一个单独的用括弧括起来的的 ``参数" 定义和调用宏, 参数在 宏扩展的时候成为类似 printf() 那样的函数的整个参数列表。

明显的缺陷是调用者必须记住使用一对额外的括弧。

gcc 有一个扩展可以让函数式的宏接受可变个数的参数。 但这不是标准。另一种 可能的解决方案是根据参数个数使用多个宏 (DEBUG1, DEBUG2, 等等), 或者用逗号玩个这样的花招:

C99 引入了对参数个数可变的函数式宏的正式支持。在宏 ``原型" 的末尾加上符号 ... (就像在参数可变的函数定义中), 宏定义中的伪宏 __VA_ARGS__ 就会在调用是 替换成可变参数。

最后, 你总是可以使用真实的函数, 接受明确定义的可变参数

如果你需要替换宏, 使用一个 函数和一个非函数式宏, 如 #define printf myprintf

0b1331709591d260c1c78e86d0c51c18.png

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/527291.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

linux看java堆大小,linux 改java堆内存大小

linux 改java堆内存大小[2021-02-08 23:06:29] 简介:linux查内存大小的方法:首先打开应用程序;然后选择系统工具选项,并单击系统终端选项;接着在系统终端命令行输入【free -h】命令;最后在结果中找到total即可查看到系…

arch linux简体中文,User-mode Linux (简体中文)

本文或本节需要翻译。要贡献翻译,请访问简体中文翻译团队。什么是 user-mode-linux?User-mode-linux (UML) 是让一个linux作为一个独立进程运行在另一个linux上。 请在[1] 查找 uml 的详细安装使用指南。这篇 wiki 文章是 这帖[失效链接 2020-08-06 ⓘ] 概要。 如果…

cad常用字体包_CAD制图初学入门如何学好CAD?CAD大神总结5点诀窍,必须收藏

现在有很多的小伙伴们都加入到了CAD这个大家庭中,一开始都是都是一脸懵的状态,更不知要从何入手!小编才开始也是,但是只要掌握好CAD的技巧和脊髓,一切都不是事。CAD大神总结5点诀窍,悄悄告诉你,…

栈windows linux,Linux+Windows: 程序崩溃时,在 C++ 代码中,如何获取函数调用栈信息...

一、前言程序在执行过程中 crash 是非常严重的问题,一般都应该在测试阶段排除掉这些问题,但是总会有漏网之鱼被带到 release 阶段。因此,程序的日志系统需要侦测这种情况,在代码崩溃的时候获取函数调用栈信息,为 debug…

oracle rollup分组没有数据时为0_数据库周刊19│GBASE适配鲲鹏;MySQL窗口函数;OGG双向数据同步……...

摘要:墨天轮数据库周刊第19期发布啦,每周1次推送本周数据库相关热门资讯、精选文章、干货文档。本周分享GBASE适配鲲鹏; 疫情激活COBOL语言;TiDB数据库的未来;Oracle与double write;MySQL8.0 窗口函数&…

c语言中语句作用,学习C语言的用途~

原标题:学习C语言的用途~C是基础的语言C语言被广泛用于操作系统和编译器的开发功能非常强虽然现在不是最流行但是最基础的东西是也比较好学的语言如:金山的创始人江明从30多岁开始学语言学的就是C对C的评价相当高C语言是一种计算机程序设计语言。它既有高级语言的特…

攻击linux的samba,Samba 中间人攻击漏洞(CVE-2015-5296)

Samba 中间人攻击漏洞(CVE-2015-5296)发布日期:2015-12-19更新日期:2016-01-01受影响系统:Samba Samba 4.x-4.1.22Samba Samba 4.3.x-4.3.3Samba Samba 4.2.x-4.2.7Samba Samba 3.x描述:CVE(CAN) ID: CVE-2015-5296Samba是在Linux…

android按钮变输入框动画,AnimShopButton 仿饿了么加入购物车旋转控件 - 自带闪转腾挪动画 的按钮。自带海量可定制 UI 属性。在 Re @codeKK Android开源站...

A shopping cart button with a telescopic displacement rotation animation ...一个仿饿了么 带伸缩位移旋转动画的购物车按钮注意,本控件非继承自ViewGroup,而是纯自定义 View,实现的仿饿了么加入购物车控件,自带闪转腾挪动画的按钮。图 1…

表格外粗内细怎么设置_金游艇复刻机芯-N厂灰游艇价格 | 复刻表评测

GM厂劳力游艇名仕型系列,官方2019年度机芯搭配全线更新为cal. 3235机芯,同时,在表盘六点位上有劳力皇冠的防伪LOGO。GM厂经历一年,在3135的基础上开发一体出3235机芯,功能与结构等完美还原于正品机芯。而且&#xff0c…

html中输出语句怎么写,javascript怎么输出?

JavaScript怎么输出?输出方式有哪些?下面本篇文章就给大家介绍JavaScript的几种输出方式,希望对大家有所帮助。方法1:使用window.alert()进行输出window.alert()方法用于显示带有一条指定消息和一个【确认】 按钮的警告框。代码示…

cron每2天跑一次_直购直测,进口新极光每2年或34000公里才需要保养一次?

我们选择以第 2 代揽胜极光P200 R-Dynamic S 车型,作为执行 [ 直购直测 ] 单元的第 12 辆车款,而在先前包含购车篇说明选择原因、油耗测试篇带大家一探具备轻油电技术的极光 P200 R-Dynamic S 油耗表现后,本次则是要带大家看看揽胜极光回厂定…

html中basefont标签,HTML的basefont标签

HTML 标签只有 Internet Explorer 支持 标签。应该避免使用该标签。定义和用法 ( 推荐学习:html教程 )标签定义基准字体。该标签可以为文档中的所有文本定义默认字体颜色、字体大小和字体系列。HTML 与 XHTML 之间的差异在 HTML 4.01 中,不赞成使用 ba…

linux mv 保持目录结构_(三)Linux系统目录结构

点击蓝字 关注我们Linux系统目录结构:所有的类Unix系统根分区下的文件系统都基本一致。分别介绍一下功能:/bin:所有常用的可执行的二进制文件,就是“命令”,这些命令是所有用户都可以使用的。(存放系统命令的目录&…

d3.js html显示图片,d3.js v4:如何在鼠标点击节点后显示图像

在使用d3.js时仍然相当缺乏经验,我碰到了一个障碍。 希望有人能帮助我。d3.js v4:如何在鼠标点击节点后显示图像我试图在鼠标单击图形中的节点时显示图片。 理想情况下,我想单击几个节点并显示图像。双击节点应该删除图像。点击背景将删除所有…

语言速算24点的小窍门_4秒钟1道题!12岁少年三夺24点大赛冠军

数学文化节上,参加大赛的孩子们。夺得24点大赛冠军的华跃麟。本报讯 (重庆晨报上游新闻记者 秦健)“哇,太厉害了。”“快快快,超过他们俩了!”昨天下午,“第二届重庆数学文化节”在重庆市德普外国语学校体育活动中心举…

用计算机表白我不喜欢你了,隐藏式表白,表白不一定要用“我喜欢你”这几个字...

要知道女生都是喜欢浪漫的,浪漫不失为一种提升表白成功率的方式。但表白的时候,如果只是一束鲜花,一句简单“我喜欢你”,难免显得太过乏味,而且不够浪漫。那该怎么给表白添加一点新意和浪漫呢?下面,是小编…

切片分析报告格式_社科论文写作101-APA数据分析结果报告格式

什么比写论文更惨?改论文!!特别是搞量化数据的,少个数据或报告格式不正确的话,重新搞数据和格式吧——又要打开spss,又要在网上看数据分析步骤,又要在熟悉的word界面花上一天。所以,…

如何关闭借呗订阅开通通知_支付宝花呗借呗隐藏规则,芝麻分600以上,花呗3.6万,借呗12万!...

阅读本文前,请您先点击上面的“蓝色字体”,再点击“关注”,这样您就可以继续免费收到文章了。每天都有分享,完全是免费订阅,请放心关注。 注:本文转载自网络,侵删经常遇到网友反馈,…

骁龙660是32位还是64位_微软公布v2004最低处理器要求,放弃32位系统,你的CPU还能支持吗?...

最近关于win10 20H1(win10更新五月版)的消息铺天盖地席卷而来,据说只有开发者用户可以先行在MSDN订阅网站下载该版本的ISO镜像文件,对于主流消费者而言,预计要再煎熬等到28日。而且微软也提前更新支持文档,…

中石油《计算机应用基础》,2017中国石油大学《计算机应用基础》第3阶段在线作业.doc...

2017中国石油大学《计算机应用基础》第3阶段在线作业.doc (23页)本资源提供全文预览,点击全文预览即可全文预览,如果喜欢文档就下载吧,查找使用更方便哦!19.90 积分窗体顶端1(2.0分)在Excel2010的工作表中,假定C3:C8区…