深入浅出可变参数函数的使用技巧本文主要介绍可变参数的函数使用,然后分析它的原理,程序员自己如何对它们实
现和封装,最后是可能会出现的问题和避免措施。
VA函数(variable argument function),参数个数可变函数,又称可变参数函数
。C/C++编程中,系统提供给编程人员的va函数很少。*printf()/*scanf()系列函数
,用于输入输出时格式化字符串;exec*()系列函数,用于在程序中执行外部文件(
main(int argc,char*argv[]算不算呢,与其说main()也是一个可变参数函数,倒不
如说它是exec*()经过封装后的具备特殊功能和意义的函数,至少在原理这一级上有
很多相似之处)。由于参数个数的不确定,使va函数具有很大的灵活性,易用性,对
没有使用过可变参数函数的编程人员很有诱惑力;那么,该如何编写自己的va函数
,va函数的运用时机、编译实现又是如何。作者借本文谈谈自己关于va函数的一些
浅见。
一、 从printf()开始
从大家都很熟悉的格式化字符串函数开始介绍可变参数函数。
原型:int printf(const char * format, ...);
参数format表示如何来格式字符串的指令,…
表示可选参数,调用时传递给"..."的参数可有可无,根据实际情况而定。
系统提供了vprintf系列格式化字符串的函数,用于编程人员封装自己的I/O函数。
int vprintf / vscanf(const char * format, va_list ap); // 从标准输入/输出
格式化字符串
int vfprintf / vfsacanf(FILE * stream, const char * format, va_list ap);
// 从文件流
int vsprintf / vsscanf(char * s, const char * format, va_list ap); // 从
字符串
// 例1:格式化到一个文件流,可用于日志文件
FILE *logfile;
int WriteLog(const char * format, ...)
{
va_list arg_ptr;
va_start(arg_ptr, format);
int nWrittenBytes = vfprintf(logfile, format, arg_ptr);
va_end(arg_ptr);
return nWrittenBytes;
}
…
// 调用时,与使用printf()没有区别。
WriteLog("%04d-%02d-%02d %02d:%02d:%02d %s/%04d logged out.",
nYear, nMonth, nDay, nHour, nMinute, szUserName, nUserID);
同理,也可以从文件中执行格式化输入;或者对标准输入输出,字符串执行格式化
。
在上面的例1中,WriteLog()函数可以接受参数个数可变的输入,本质上,它的实现
需要vprintf()的支持。如何真正实现属于自己的可变参数函数,包括控制每一个传
入的可选参数。
二、 va函数的定义和va宏
C语言支持va函数,作为C语言的扩展--C++同样支持va函数,但在C++中并不推荐使
用,C++引入的多态性同样可以实现参数个数可变的函数。不过,C++的重载功能毕
竟只能是有限多个可以预见的参数个数。比较而言,C中的va函数则可以定义无穷多
个相当于C++的重载函数,这方面C++是无能为力的。va函数的优势表现在使用的方
便性和易用性上,可以使代码更简洁。C编译器为了统一在不同的硬件架构、硬件平
台上的实现,和增加代码的可移植性,提供了一系列宏来屏蔽硬件环境不同带来的
差异。
ANSI C标准下,va的宏定义在stdarg.h中,它们有:va_list,va_start(),va_ar
g(),va_end()。
// 例2:求任意个自然数的平方和:
int SqSum(int n1, ...)
{
va_list arg_ptr;
int nSqSum = 0, n = n1;
va_start(arg_ptr, n1);
while (n > 0)
{
nSqSum += (n * n);
n = va_arg(arg_ptr, int);
}
va_end(arg_ptr);
return nSqSum;
}
// 调用时
int nSqSum = SqSum(7, 2, 7, 11, -1);
可变参数函数的原型声明格式为:
type VAFunction(type arg1, type arg2, … );
参数可以分为两部分:个数确定的固定参数和个数可变的可选参数。函数至少需要
一个固定参数,固定参数的声明和普通函数一样;可选参数由于个数不确定,声明
时用"…"表示。固定参数和可选参数公同构成一个函数的参数列表。
借助上面这个简单的例2,来看看各个va_xxx的作用。
va_list arg_ptr:定义一个指向个数可变的参数列表指针;
va_start(arg_ptr, argN):使参数列表指针arg_ptr指向函数参数列表中的第一个
可选参数,说明:argN是位于第一个可选参数之前的固定参数,(或者说,最后一
个固定参数;…之前的一个参数),函数参数列表中参数在内存中的顺序与函数声
明时的顺序是一致的。如果有一va函数的声明是void va_test(char a, char b, c
har c, …),则它的固定参数依次是a,b,c,最后一个固定参数argN为c,因此就是
va_start(arg_ptr, c)。
va_arg(arg_ptr, type):返回参数列表中指针arg_ptr所指的参数,返回类型为ty
pe,并使指针arg_ptr指向参数列表中下一个参数。
va_copy(dest, src):dest,src的类型都是va_list,va_copy()用于复制参数列表
指针,将dest初始化为src。
va_end(arg_ptr):清空参数列表,并置参数指针arg_ptr无效。说明:指针arg_pt
r被置无效后,可以通过调用va_start()、va_copy()恢复arg_ptr。每次调用va_st
art() / va_copy()后,必须得有相应的va_end()与之匹配。参数指针可以在参数列
表中随意地来回移动,但必须在va_start() … va_end()之内
相关推荐
ansys maxwell
matlab基于不确定性可达性优化的自主鲁棒操作.zip
文件操作、数据分析和网络编程等。Python社区提供了大量的第三方库,如NumPy、Pandas和Requests,极大地丰富了Python的应用领域,从数据科学到Web开发。Python库的丰富性是Python成为最受欢迎的编程语言之一的关键原因之一。这些库不仅为初学者提供了快速入门的途径,而且为经验丰富的开发者提供了强大的工具,以高效率、高质量地完成复杂任务。例如,Matplotlib和Seaborn库在数据可视化领域内非常受欢迎,它们提供了广泛的工具和技术,可以创建高度定制化的图表和图形,帮助数据科学家和分析师在数据探索和结果展示中更有效地传达信息。
信息安全课程实验C++实现DES等算法源代码
环境 python >= 3.6 pyahocorasick==1.4.2 requests==2.25.1 gevent==1.4.0 jieba==0.42.1 six==1.15.0 gensim==3.8.3 matplotlib==3.1.3 Flask==1.1.1 numpy==1.16.0 bert4keras==0.9.1 tensorflow==1.14.0 Keras==2.3.1 py2neo==2020.1.1 tqdm==4.42.1 pandas==1.0.1 termcolor==1.1.0 itchat==1.3.10 ahocorasick==0.9 flask_compress==1.9.0 flask_cors==3.0.10 flask_json==0.3.4 GPUtil==1.4.0 pyzmq==22.0.3 scikit_learn==0.24.1 效果展示 为能最简化使用该系统,不需要繁杂的部署各种七七八八的东西,当前版本使用的itchat将问答功能集成到微信做演示,这需要你的微信能登入网页微信才能使用itchat;另外对话上下文并没
一个高品质的音乐共享和流媒体轻量音乐程序网站在线音乐源码,是创建您自己的音乐流媒体网站的最佳方式! 最新版本: 添加插件系统,现在开发人员可以为程序制作插件并在更新后保留您的自定义设置。 固定的2 个以上的小错误。 安装所需:nginx/apache,mysql5.6+,php7+ 搭建说明:看源码内详细说明
实现的金融风控贷款违约预测python源码.zip实现的金融风控贷款违约预测python源码.zip实现的金融风控贷款违约预测python源码.zip实现的金融风控贷款违约预测python源码.zip实现的金融风控贷款违约预测python源码.zip实现的金融风控贷款违约预测python源码.zip实现的金融风控贷款违约预测python源码.zip实现的金融风控贷款违约预测python源码.zip实现的金融风控贷款违约预测python源码.zip实现的金融风控贷款违约预测python源码.zip实现的金融风控贷款违约预测python源码.zip
麦肯锡—xx数码公司发展战略咨询报告.ppt
FT_Prog_v3.12.38.643--FTD USB 工作模式设定及eprom读写
基于sklearn实现线性回归模型对波士顿房价进行预测源码.zip
文件操作、数据分析和网络编程等。Python社区提供了大量的第三方库,如NumPy、Pandas和Requests,极大地丰富了Python的应用领域,从数据科学到Web开发。Python库的丰富性是Python成为最受欢迎的编程语言之一的关键原因之一。这些库不仅为初学者提供了快速入门的途径,而且为经验丰富的开发者提供了强大的工具,以高效率、高质量地完成复杂任务。例如,Matplotlib和Seaborn库在数据可视化领域内非常受欢迎,它们提供了广泛的工具和技术,可以创建高度定制化的图表和图形,帮助数据科学家和分析师在数据探索和结果展示中更有效地传达信息。
文件操作、数据分析和网络编程等。Python社区提供了大量的第三方库,如NumPy、Pandas和Requests,极大地丰富了Python的应用领域,从数据科学到Web开发。Python库的丰富性是Python成为最受欢迎的编程语言之一的关键原因之一。这些库不仅为初学者提供了快速入门的途径,而且为经验丰富的开发者提供了强大的工具,以高效率、高质量地完成复杂任务。例如,Matplotlib和Seaborn库在数据可视化领域内非常受欢迎,它们提供了广泛的工具和技术,可以创建高度定制化的图表和图形,帮助数据科学家和分析师在数据探索和结果展示中更有效地传达信息。
基于相干衍射成像模拟的matlab源码.zip
项目介绍 背景 在当今的数字化时代,远程监控系统已经成为企业和个人必不可少的工具。随着物联网(IoT)技术的发展,监控系统的需求不断增加,不仅仅局限于视频监控,还包括数据监控、设备状态监控等。基于CS(Client-Server)架构的远程监控系统应运而生,旨在提供高效、实时、可靠的监控服务,帮助用户实现远程管理和控制。 目的 基于CS的远程监控系统软件项目旨在为用户提供一个综合性的监控平台,通过该平台,用户可以实时监控各类设备和数据,实现远程控制和管理,提高工作效率,降低运营成本。同时,该系统还可以用于安全防护、生产过程监控等多种场景,具有广泛的应用前景。 模块说明 前端模块 前端模块是用户与系统交互的界面,负责展示监控数据和接收用户指令。前端模块的主要功能包括: 用户登录与认证:通过安全的登录机制,确保只有授权用户才能访问系统。 实时数据展示:以图表、仪表盘等形式展示实时监控数据,包括视频流、传感器数据等。 报警通知:当监控系统检测到异常情况时,前端模块会通过弹窗、声音等方式通知用户。 远程控制:用户可以通过前端界面对设备进行远程控制,例如开关设备、调整参数等。
网课专注度监测预警系统基于yolov5目标检测的网课专注度检测系统源码+模型+pyqt5界面.zip
matlab基于标签歧义的深度标签分布学习.zip
九型人格测试题.144题dr.xls
麦肯锡—xx科技业务流程改造报告.ppt
文件操作、数据分析和网络编程等。Python社区提供了大量的第三方库,如NumPy、Pandas和Requests,极大地丰富了Python的应用领域,从数据科学到Web开发。Python库的丰富性是Python成为最受欢迎的编程语言之一的关键原因之一。这些库不仅为初学者提供了快速入门的途径,而且为经验丰富的开发者提供了强大的工具,以高效率、高质量地完成复杂任务。例如,Matplotlib和Seaborn库在数据可视化领域内非常受欢迎,它们提供了广泛的工具和技术,可以创建高度定制化的图表和图形,帮助数据科学家和分析师在数据探索和结果展示中更有效地传达信息。
1-8