C++不定参数个数函数的写法

2023-11-09

C++不定参数个数的函数比较常见,比如printf,先写一个字符串,在字符串里有0个或多个%,每个%要对应后面一个数据或者字符之类的东西,理论上有多少个%都是没问题的,难不成还要搞几亿个printf的重载吗?

nonono,这个时候就要用到C++一个神奇的符号——“…”

“…”可以取代一系列相同类型的参数,编译器不关系这一串参数有多少个,类型是什么,但要求省略号之前必须有一个确定类型的参数,就比如printf的第一个参数一定是个字符串。

至于对省略号里面参数的调用,需要用到几个看起来比较高大上的东西。

下面以将几个数加和的函数int add(int n,…)为例(n代表后面的参数个数):
首先是一种新的类型va_list,跟int,double,float一样,就是一种数据类型,至于具体是啥在内存中怎么存储的我们不关心。在使用省略号里边参数时第一步需要做的就是声明一个va_list型的变量,这里我们记为arg_ptr(因为这种写法比较普遍吧)。然后是两个函数,一个是va_start,它是一个操作函数,返回值是void,有两个参数,第一个就是arg_ptr,第二个是则是省略号之前的那个参数,这里就是n,它的作用就是将arg_ptr这个类似指针的东西指向省略号中的第一个参数。第二个函数时va_arg,va_arg函数将返回 arg_ptr 所指位置的值,并将 arg_ptr 指向下一个参数
最后还需要用一个函数va_end(arg_ptr)来释放这个va_list。

写出来就是这个样子:

long long add(int n, ...) {
	va_list arg_ptr;
	va_start(arg_ptr, n);
	long long ans = 0;
	for (int i = 0; i < n; ++i) {
		ans += va_arg(arg_ptr, int);
	}
	va_end(arg_ptr);
	return ans;
}

当然,如果需要的话,你也可以规定省略号内参数的类型:

long long add(int n, int...) {
	va_list arg_ptr;
	va_start(arg_ptr, n);
	long long ans = 0;
	for (int i = 0; i < n; ++i) {
		ans += va_arg(arg_ptr, int);
	}
	va_end(arg_ptr);
	return ans;
}

了解了省略号的用法,就可以自己写出printf了,大致思路就是将字符串从头到尾进行扫描,如果碰到%就从后面的省略号中拿一个参数。当然真正的printf还是要考虑更多的事情的,比如如果%d的位置从省略号中拿了一个字符串就应该抛出什么样的错误,如果从省略号中拿出了一个浮点数还要在抛出异常的同时考虑将浮点数转化为整数“糊弄”过去,姑且输出一个东西。

当然,上面自己写的printf中还是要使用printf本身的,因为我们不知道printf更底层的东西,我们做的就是把单纯输出括号中东西的printf转化成了能支持%输出的printf仅此而已

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

C++不定参数个数函数的写法 的相关文章

  • 打击垃圾邮件机器人

    我的网站中有 C 表单 希望防止垃圾邮件机器人填写它 诀窍是 我想避免 CAPTHA 或任何其他用户输入 以避免丢失单个注册 以下是我心中的一些技巧 隐藏输入栏 问题 这还有效吗 跟踪时间 从第一个用户输入 关注名字 到发布表单 人类需要
  • C语言中的递归是如何工作的?

    我试图了解 C 中递归的工作原理 任何人都可以给我解释控制流吗 include
  • C++ 返回值、引用、const 引用

    你能向我解释一下返回值 值引用和值常量引用之间的区别吗 Value Vector2D operator const Vector2D vector this gt x vector x this gt y vector y return t
  • 如何使用 ILoggerFactory 记录 Polly 的重试

    或者 如何从静态方法记录 From https github com App vNext Polly https github com App vNext Polly你有这样的例子 其中记录器神奇地可用 Policy Timeout 30
  • MySql 最后插入 ID,连接器 .net

    我正在使用 MySql Connector net 我需要获取最后一个查询生成的插入 id 现在 我假设返回值是MySqlHelper ExecuteNonQuery应该是最后一个插入id 但它只返回1 我正在使用的代码是 int inse
  • 每次调用新方法时触发事件

    我正在做一个logger for a c 应用程序需要记录每个方法被调用的时间以及每个方法执行时间 我可以通过调用自己的方法来做到这一点EventLogger LogMethodCall方法在每个方法的开头 但我想知道是否有办法使CLR每次
  • 如何启动异步任务对象

    我想开始收集Task同时处理对象并等待所有对象完成 下面的代码显示了我想要的行为 public class Program class TaskTest private Task createPauseTask int ms works w
  • 使用预编译头减少 clang 编译时间

    我正在开发一个数据库项目 该项目将查询 以某种高级语言表示 编译为 C 代码 这段代码由数据库编译并执行 那部分工作得很好 现在 我正在尝试减少 C 查询代码的编译时间 我想知道是否可以使用预编译头来提高性能 该查询被转换为一个名为 Que
  • 无缝滚动瓷砖地图

    我正在开发一个自上而下的角色扮演游戏 并且想要实现无缝滚动地图 也就是说 当玩家探索世界时 地图之间没有加载屏幕 也没有通往下一个区域的 门 我有两种方法可以打破世界 在顶层 我有 区域 它只是 9 个 地图 的集合 这些区域仅由目录表示
  • StreamReader,C#,peek

    我有一个 StreamReader 它偶尔会检查它是否有更多内容可以从简单的文本文件中读取 它使用 peek 属性 问题是 当我使用 peek 时 位置发生了变化 尽管不应该发生 FileStream m fsReader new File
  • 使用 size_t 值反向遍历向量

    我想以相反的方向遍历向量的值 如您所知 向量的大小为 size t 当我使用以下代码时 for size t r m size 1 r gt 0 r x r f r for size t c r 1 c lt m size c x r m
  • 在 C++ 中使用表达式模板进行符号微分

    如何在 C 中使用表达式模板实现符号微分 一般来说 您需要一种表示符号的方法 即编码的表达式模板 例如3 x x 42 以及一个可以计算导数的元函数 希望您对 C 中的元编程足够熟悉 知道这意味着什么和需要什么 但可以给您一个想法 This
  • 是否有一种算法可以在线性时间内计算数组反转?

    我知道有多少倒转 en wikipedia org wiki Inversion 28discrete mathematics 29 in an n 元素数组可以在 O n log n 操作使用增强型归并排序 http www geeksf
  • 将一个整数从 C 客户端发送到 Java 服务器

    我使用此代码将一个整数从我的 Java 客户端发送到我的 Java 服务器 int n rand nextInt 50 1 DataOutputStream dos new DataOutputStream socket getOutput
  • 按值返回的函数的返回语句中的初始化

    我的问题源于深入研究std move in return语句 例如以下示例 struct A A std cout lt lt Constructed lt lt this lt lt std endl A A noexcept std c
  • 带有自定义鉴别器的 EntityFramework Code First 继承

    我正在尝试在 EntityFramework Code First 中映射以下继承 public class Member public string ProjectName get set public string AssemblyNa
  • SQL参数化查询不显示结果

    我的 DataAcess 类中有以下函数 但它没有显示任何结果 我的代码如下 public List
  • 从 exit() 和 fork() 返回的结果奇怪地发生了位移

    我有一个 C 代码 有时会自行分叉 每个分叉都会执行一些操作 然后返回一个错误代码 目前 每个子进程返回其 ID 0 n void other int numero exit numero int main for int i 0 i lt
  • 从 STL 列表中删除项目

    我想创建一个函数 如果符合特定条件 则将项目从一个 STL 列表移动到另一个列表 这段代码不是这样做的方法 迭代器很可能会被擦除 函数失效并导致问题 for std list
  • 如何在没有 Visual Studio 的情况下将新文件添加到 .csproj 文件

    如何添加新文件到 csproj从命令提示符 我认为没有任何工具可以响应命令行上的 add project 命令来执行此操作 但我认为您可以幸运地创建一个程序 脚本来直接操作 csproj 文件的 XML 内容 csproj 文件的结构如下所

随机推荐

  • 警惕!这个微软Office 0day 已遭在野利用

    聚焦源代码安全 网罗国内外最新资讯 编译 代码卫士 安全研究员发现 微软Office 新0day 已遭在野利用 仅需打开一份Word文档 攻击者即可利用该漏洞通过Microsoft 诊断工具 MSDT 执行恶意PowerShell 命令 C
  • 【优化无功】教与学算法求解IEEE_33节点无功优化问题【含Matlab源码 2699期】

    一 教与学算法 TLBO 由Rao等人在2011年提出的 是一种基于群体的启发式优化算法 不需要任何算法特定参数 这种方法模拟了传统的课堂教学过程 整个优化过程包括教师阶段和学习者阶段 在教师阶段 每个学生都向最优秀的个体进行学习 在学习阶
  • 解决std::to_string(long double _Val)函数当浮点数的精度大于等于小数点后六位时,返回的字符串结果为”科学计数法”的形式

    解决std to string long double Val 函数当浮点数的精度大于等于小数点后六位时 返回的字符串结果为 科学计数法 的形式 并且去掉末尾无效的 0 代码如下 include
  • Universal Model:基于clip驱动的器官分割和肿瘤检测通用模型

    论文 https arxiv org abs 2301 00785 我看这篇主要是看看MRI的多模态融合方法的 所以会略一些东西 感兴趣细节的就翻原文好嘞 摘要 越来越多的公共数据集在自动器官分割和肿瘤检测方面显示出显著的影响 然而 由于每
  • 设置Crontab执行任务时不发送邮件

    crontab的定时任务执行后都会给root发送一封邮件 通过以下方法可以防止这种情况 SHELL bin bash PATH sbin bin usr sbin usr bin 这是第一种方法 设置MAILTO参数为空 MAILTO HO
  • 微信网页版接口详解

    一 网页版微信提供的HTTP接口 1 获取uuid 说明 用于获取显示二维码以及登录所需的uuid 标识获取二维码和扫码的为同一个用户 请求方式 GET 地址 https login wx qq com jslogin get参数 参数 示
  • WSL安装及部分报错

    WSL安装 成功过程 错误示范 第一次进行操作时 第二次安装wsl 成功过程 结合使用了微软商城的评论区的建议 在链接https wsldownload azureedge net Ubuntu 2004 2020 424 0 x64 ap
  • JAVA语言中“+”号的三种用法

    一 数字相加 当 号两边都是数字时 代表数字相加 例如 int a 1 2 a的值为3 二 字符串连接 当 号两边至少有一个是字符串时 代表字符串连接 例如 String str hello world str的值为 helloworld
  • 如何使用Mac终端给树莓派pico构建C/C++程序进行开发,以及遇到各种问题该怎么处理,不使用任何IDE或编辑器(例如VS Code)

    写本文的原因是官方的教程已经过时了 如果你现在按照官方教程来在 Mac 上进行配置 那么会遇到一堆问题 比如我几乎把能踩的 雷 都踩了 所以这里记录了完整过程 以及各种错误的原因和处理方法 不然以后换 Mac 了或者在其他平台遇到同样的问题
  • 以太坊json rpc

    Contents Hash List JSON RPC support HEX value encoding The default block parameter Curl Examples Explained JSON RPC meth
  • HCIP-DATACOM-带解析-101-150题(821)

    101 VRP平台上 当我们引入OSPF路由到ISIS的时候 如果不指定COST 开销值将默认设为16 A 正确 B 错误 正确答案 B 答案解析 102 使用如下IP前缀列表进行路由匹配 则以下哪项路由可以被匹配到 ip ip prefi
  • 【Python】Python元组学习

    Python之元组学习记录 一 元组的特点 可以容纳多个数据 可以容纳不同类型的数据 混装 数据是有序存储的 下标索引 允许重复数据存在 不可以修改 增加或删除元素等 但内部list元素可以被修改 支持while for循环 二 元组操作练
  • [现代控制理论]4_PhasePortrait爱情故事动态系统分析

    现代控制理论 11 现代控制理论串讲 完结 pdf获取 现代控制理论 10 可观测性与分离原理 观测器与控制器 现代控制理论 9 状态观测器设计 龙伯格观测器 现代控制理论 8 5 线性控制器设计 轨迹跟踪simulink 现代控制理论 8
  • QFileDialog 对话框类

    QFileDialog 对话框类 QFileDialog 对话框类是 QDialog 类的子类 通过这个类可以选择要打开 保存的文件或者目录 关于这个类我们只需要掌握一些静态方法的使用就可以了 通用参数 parent 当前对话框窗口的父对象
  • Navicat导出整个数据库

    Navicat使用 转存为SQL文件的方式导出数据库 如果有外键会导致在导入时出错 需使用数据传输的方式进行导出 选成使用文件方式进行保存 高级选项需选成 这样导出的SQL脚本就是完整版本的 在新数据库中导入不般不会报错 如果出现导入报错
  • MySQL国内镜像

    一 基础概念 MySQL是一种关系型数据库管理系统 使用标准SQL查询语句进行数据访问 广泛应用于Web系统的数据存储 MySQL国内镜像指的是在国内建立的MySQL镜像站点 用于提供MySQL的各种资源下载和服务 由于MySQL在国内访问
  • A *p=new B;

    好久没有摸c 了 刚刚看到个面试题 发现都要忘了 巩固下 A P new B A是父类 B是子类 虽然P是一个基类的指针 但是new B调用的是派生类B的构造方法 所以构造的是B类对象 先调用A的构造函数 再调用B的构造函数 构造完后会返回
  • 【计算机操作系统】第一章、操作系统引论

    参考书籍为汤老师经典教材 本博客旨在作为自己学习笔记并与大家分享 1 操作系统的目标和作用 1 1 目标 方便 有效 可扩充 开放性 1 2 作用 作为用户和计算机硬件系统之间的接口 用户可以通过1 命令方式2 系统调用方式3 图形 窗口方
  • 生产环境数据库版本太低导致:PostgreSQL - ERROR: could not determine data type of parameter $1

    1 分析 这个问题一般值前端传回来的参数和实体类或者数据库不匹配 2 报错的sql LIKE CONCAT query areaName 3 报错问题 PostgreSQL ERROR could not determine data ty
  • C++不定参数个数函数的写法

    C 不定参数个数的函数比较常见 比如printf 先写一个字符串 在字符串里有0个或多个 每个 要对应后面一个数据或者字符之类的东西 理论上有多少个 都是没问题的 难不成还要搞几亿个printf的重载吗 nonono 这个时候就要用到C 一