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,一经查实,立即删除!

相关文章

python梦幻西游鼠标偏移_【按键盒子】梦幻西游解决鼠标漂移问题

Gosub GetFbl//Gosub 点击任务红名/////获取窗口分辨率///Sub GetFbl//左上角找图FindPic 0, 0, 1024, 768, "Attachment:\zsj.bmp", 0.9, intX1, intY1If intX1 < 0MessageBox "未找到窗口左上角"Else//定位窗口右下角Delay 10FindPic 0, 0, 1024, 768…

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

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

脉冲宽度调制pdm_PWM (脉冲宽度调制)原理与实现

原理与实现1、PWM原理2、调制器设计思想3、具体实现设计一、PWM(脉冲宽度调制Pulse Width Modulation)原理&#xff1a;脉冲宽度调制波通常由一列占空比不同的矩形脉冲构成&#xff0c;其占空比与信号的瞬时采样值成比例。图1所示为脉冲宽度调制系统的原理框图和波形图。该系统…

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

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

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

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

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

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

python vbs库_Python语言之requests库

发送请求、传递URL参数、定制headers、接受数据&#xff0c;处理数据等在Java中用httpclient jar包&#xff0c;在Python中用requests库&#xff0c;即使没有事先下载&#xff0c;在Pycharm开发工具中&#xff0c;出现提示时刻&#xff0c;同意安装即可1) 发送请求urlhttp://ba…

Linux中fdisk对应的c函数,linux下fdisk命令实战案例之详解

一、fdisk命令中参数介绍&#xff1a;1.查看硬盘使用情形#fdisk -l 观察硬盘之实体使用情形2.fdisk /dev/sda&#xff0c;进入硬盘分割模式1. 输入 m 显示所有命令列示。2. 输入 p 显示硬盘分割情形。3. 输入 a 设定硬盘启动区。4. 输入 n 设定新的硬盘分割区。4.1. 输入 e 硬盘…

cvs有机添加剂检测_美国ECI CVS 电镀添加剂分析仪QL-10EX

美国ECI CVS 电镀添加剂分析仪型 号&#xff1a;QL-10EX价 格&#xff1a;美国ECI CVS 电镀添加剂分析仪QL-10EXQL-5EX, QL-10EX,旧型号&#xff1a;QL-5E,QL-5, QL-10E,QL-10,QP-4000,QLC-5000产品介绍别名&#xff1a;电镀分析仪 循环剥离伏安测试仪 CVS测试仪 电镀成份分…

linux多台主机对比文件大小,Linux主机df和du出来的文件和磁盘大小不相同

df 查看磁盘大小和使用空间的命令 常用的是df -hdu 查看文件或者文件夹大小的命名 常用的是du -sh *一、问题现象的陈述1、先列出df的结果# df -hFilesystem Size Used Avail Use% Mounted on/dev/xvda1 20G 17G 2.3G 88% /tmpfs 1.9G 0 1.9G …

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

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

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

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

c语言字符型计算器,求用c语言编程四则混合运算计算器?

#include#include#includechar token[61]; /*存放表达式字符串的数组*/int n0;void error(void) /*报告错误函数*/{printf("ERROR!\n");exit(1);}void match(char expected) /*检查字符匹配的函数*/{if(token[n]expected)token[n]getchar();else error();}double ter…

qt写python教程视频_GitHub - qtg666/codeparkshare: Python初学者(零基础学习Python、Python入门)书籍、视频、资料、社区推荐...

PythonSharePython初学者(零基础学习Python、Python入门)书籍、视频、资料、社区推荐本文 主要 针对 零基础 想学习Python者。本文本文由史江歌(shijianggegmail.com QQ:499065469)根据互联网资料收集整理而成&#xff0c;感谢互联网&#xff0c;感谢各位的分享。鸣谢&#xff…

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

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

C语言如何编辑资源文件,用C语言做个简单的计算机,上面是代码,请教上资源文件在哪里编写,要新建什么文件...

当前位置:我的异常网 C语言 用C语言做个简单的计算机&#xff0c;上面是代码&#xff0c;请教上资源用C语言做个简单的计算机&#xff0c;上面是代码&#xff0c;请教上资源文件在哪里编写&#xff0c;要新建什么文件www.myexceptions.net 网友分享于&#xff1a;2013-07-30 …

换发型算法_GitHub - fredliu168/yry: yry(颜如玉)—— 一个实现人脸融合的算法,可以接近腾讯天天P图疯狂变脸功能的效果...

颜如玉颜如玉 —— python 人脸融合程序&#xff0c;可实现类似天天P图疯狂换脸、face人脸融合效果项目描述最近随着各种技术的发展&#xff0c;图像方面的人脸处理技术越来越广泛。各大相机软件都有美颜、贴图、换发型、变脸等功能。天天P图与Face也都推出人脸处理的 API&…

单片机c语言 外部中断,单片机C语言代码:外部中断,按下中断按键LED不亮,LED1正常亮...

该楼层疑似违规已被系统折叠 隐藏此楼查看此楼* 名称&#xff1a;外部中断* 日期&#xff1a;2013-9-10* 晶振:11.0592MHZ******************************************************************/#include //包含头文件&#xff0c;对IO进行定义&#xff0c;可以选中后右击&…

电脑生成siri语音_Siri for Mac:苹果电脑也有语音助手

今天&#xff0c;美国专利和商标局公布了苹果的一项长达92页的专利申请&#xff0c;描述了一种功能和复杂程度远远超过目前 Mac 听写功能的技术&#xff0c;这些功能介绍可以被简单的总结成 Siri for Mac。这项专利被称为“桌面环境下的智能数字助理”。苹果 Siri 在2011年登陆…

c语言 手动实现sizeof,sizeof究竟是怎样实现的?

sizeof&#xff0c;是在编译的时候&#xff0c;查找符号表&#xff0c;判断类型&#xff0c;然后根据基础类型来取值的&#xff0c;如果是struct则是看类型声明符号表来判定&#xff0c;如果字符串则是通过常量表来判断&#xff0c;具体可以参考编译原理的符号表管理章节&#…