C++传递不定参函数
定义不定参数函数,要用到下面这些宏:
- va_start(ap, farg): 初始化一个va_list变量ap,farg是第一个形参
- va_arg(ap, type): 获取(下)一个type类型的参数
- va_end(ap): 结束使用ap
C语言里编写不定参数函数的形式是这样的:
#include <stdarg.h>
int sum(int cnt,...) {
int sum = 0;
int i;
va_list ap;
va_start(ap, cnt);
for(i = 0; i < cnt; ++i)
sum += va_arg(ap, int);
va_end(ap);
return sum;
}
定义不定参数函数,要用到下面这些宏:
- va_start(ap, farg): 初始化一个va_list变量ap,farg是第一个形参
- va_arg(ap, type): 获取(下)一个type类型的参数
- va_copy(ap): 用于复制参数列表
- va_end(ap): 结束使用ap
这些宏定义一般在stdarg.h
里。
typedef char * va_list;
#define _INTSIZEOF(n) ( (sizeof(n) + sizeof(int) - 1) & ~(sizeof(int) - 1) )
#define va_start(ap,v) ( ap = (va_list)&v + _INTSIZEOF(v) )
#define va_arg(ap,t) ( *(t *)((ap += _INTSIZEOF(t)) - _INTSIZEOF(t)) )
#define va_end(ap) ( ap = (va_list)0 )
注意: 上面这些宏定义会因不同的系统和不同的处理器架构而不同
_INTSIZEOF宏
_INTSIZEOF这个宏的位运算意义比较难理解,乍一看以为是表示多少个int型的长度,其实它运算出来的结果是按照int型对齐后的长度。比如int型为4个字节,_INTSIZEOF(1)、_INTSIZEOF(2)、_INTSIZEOF(3)、_INTSIZEOF(4)的结果都是4,_INTSIZEOF(5)、_INTSIZEOF(6)、_INTSIZEOF(7)、_INTSIZEOF(8)的结果都是8,这正是x86架构CPU下的参数传递方式,32位即4字节对齐。
几个注意事项
- 不定参数的函数至少要有一个固定的参数,因为要用它来初始化va_list,比如上面代码中sum函数的cnt参数,同时它也表明了传递的参数的个数。
常用方式
不定参数函数最常用来格式化字符串,一个比较常见的场景是我们想输出一些log消息,但又不能直接在控制台输出,需要自己写一个log函数来格式化log消息并输出。这时我们可以用vsprintf函数:
void log(const char *format, ...) {
char buf[MAX_BUF_SIZE];
va_list ap;
va_start(ap, format);
vsprintf(buf, format, ap);
OUTPUT(buf);
}
vsprintf函数的前两个参数和sprintf的前两个参数意义相同,只不过后面的不定参换成了va_list类型的参数列表,这正是让我们用来定义自己的格式化函数的。
https://www.cnblogs.com/luzhlon/p/7087080.html
C++传递不定参函数的更多相关文章
- Golang函数-不定参函数
Golang函数-不定参函数 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任.
- go基础之不定参函数
指定类型参数 任意类型参数的变参 go语言同其他编程一样也提供了对变参函数的支持.本文简单讲解一下go中变参函数的使用方法. 指定类型参数 不定参数是指函数传入参数的个数为不确定数量,个数需要在调用的 ...
- iOS实现传递不定长的多个参数
我们在使用苹果官方的文档的时候会发现可传不定数的参数例如: // [[UIAlertView alloc]initWithTitle:<#(nullable NSString *)#> m ...
- c++不定参数函数
不定参数当年做为C/C++语言一个特长被很多人推崇,但是实际上这种技术并没有应用很多.除了格式化输出之外,我实在没看到多少应用.主要原因是这种技术比较麻烦,副作用也比较多,而一般情况下重载函数也足以替 ...
- 不定参数函数原理以及实现一个属于自己的printf函数
一.不定参数函数原理 二.实现一个属于自己的printf函数 参考博文:王爽汇编语言综合研究-函数如何接收不定数量的参数
- def 函数的不定长函数
*args 不定长函数传值可直接传,也可以拆包传,参数默认为元组: 参数为字典的时候:
- Python不定参数函数
1. 元组形式 def test1(*args): print('################test1################') print(type(args)) print(arg ...
- 定时器(setTimeout/setInterval)调用带参函数失效解决方法
也许你曾碰到过这样的问题,不管是setInterval()还是setTimeout(),当code参数里放一个带参函数时,定时器都会失效,看下面这个例子: function test(str){ al ...
- js addEventListener调用传参函数
先看这段代码 function abc(key){ console.log(key); } for(let i=0;i<oInput.length;i++){ oInput[i].addEven ...
随机推荐
- Git flow 工作流与规范
概述 简版图: PS. 可能用到的命令: 1.从指定 commit拉出新分支 git checkout commitId -b 本地新branchName git checkout 9fbc3d0 ...
- 用ab每隔30分钟并发一次休息10分钟
linux脚本监控程序运行情况(重启程序)主要有两种情况:一种是一个可执行文件:如shell脚本文件:另一种是使用python打开的多个程序.第一种:它的进程名字由路径名字和程序名字组成,比如:我有个 ...
- Ubuntu 18 Kubernetes集群的安装和部署 以及Helm的安装
首先说一下我的环境, 我是在windows 10 上面建了一个ubuntu18的虚拟机,同时由于某些原因 不受网络限制, 所以安装比较顺利. Install 1.安装并启用 Docker sudo ...
- trie、FSA、FST(转)
add by zhj: 在学习Lucene的存储结构时,看到其使用了FST,这篇文章写的不错. trie,FSA,FST都是用来解决有限状态机的存储,trie是树,它进一步演化为FSA和FST,这两者 ...
- SQL系列(六)—— 过滤(where)
在日常的应用中的,大多数业务场景都只是需要特定的数据,所以能够过滤筛选数据显得尤为至关重要.从需求角度分析,需要特定的数据,即需要一定条件的数据,即从全量数据中根据特定条件过滤出需要的数据. 如果需要 ...
- Win10应用商城删除后部分应用出错的解决方案
出错图示 解决方案 查找完整包名:Get-AppxPackage -allusers | Select Name, PackageFullName Add-appxpackage -register ...
- (原创)理解主机设备(PLC,PC机)之间的以太网通信
主机设备:PC机,PLC 网络设备:家用路由器 局域网包括了有线局域网和无线局域网(WIFI).怎么去使用2者? 网络设备的职责最终目的为了帮助2台主机的数据传输.路由器,交换机范围不同,目的相同.在 ...
- azure跨域问题(访问azure存储账户数据,blob)
访问azure存储账户数据报错:405错误 解决方案 打开访问的存储账户--->CORS--->Blob服务 全部填写*就可以了,点击“保存”即可. iframe就可以展示blob中的pd ...
- Java自学-日期 Calendar
Java的Calendar类 Calendar类即日历类,常用于进行"翻日历",比如下个月的今天是哪天 示例 1 : Calendar与Date进行转换 采用单例模式获取日历对象C ...
- Java 基本类型包装类Wrapper
一.包装类概述 1.为什么需要包装类 Java并不是纯面向对象的语言.Java语言是一个面向对象的语言,但是Java中的基本数据类型却是不面向对象的.基本数据类型有它的优势:性能(效率高,节省空间). ...