这里只是简单的描述一下C语言中如何使用参数数量可变的函数,至于stdarg.h中关键宏如何实现以及编译器如何处理这些更底层的东西,以后再说。

我们知道,C语言中函数体包含三个要素:返回值类型、函数体、参数列表。其中参数列表一般情况下都包含个数及类型确定的参数信息,但是千万不要以为函数的参数就必须是个数确定的,其实我们每天都在用着这些例外的情况:printf(),scanf()..。这种函数的原型一般是ReturnType A (Type a,...Type b,...),第二个省略号即表示该函数参数个数为确定。那么如何在自己的代码中实现这种函数呢?

举个例子,我们想编写一个函数average(),该函数返回输入参数的平均值,但输入参数的个数是不确定的。我们通过使用stdarg.h中定义的一个数据类型va_list和三个关键宏va_start,va_arg和va_end来实现。其中va_list类型的变量用于访问参数列表中未确定的部分,这个变量通过va_start宏来初始化。该宏接受两个参数,第一个是该va_list类型的变量,第二个是省略号前面最后一个有名字的参数。初始化过程把var_list变量设置为指向可变参数部分的第一个参数。

为了在函数中访问未确定的参数部分,需要使用va_arg宏,该宏接受两个参数,第一个是前面已经被va_start宏初始化过了的va_list变量,第二个是参数列表中下一个参数的类型。

当访问完最后一个参数时,我们需要调用va_end宏。

最后给出一个实例函数 float average(int n_values,...),该函数接受一个确定参数和一个不确定参数列表。确定参数n_values表示未确定参数的个数,函数返回这些n_values个参数的平均值。代码如下:

View Code

1 #include<stdarg.h>
2 #include<iostream.h>
3  float
4 average(int n_values,...)
5 {
6 va_list var_arg;
7 int count;
8 float sum=0;
9
10
11 va_start(var_arg,n_values);
12
13 for(count=0;count<n_values;count++)
14 {
15 sum+=va_arg(var_arg,int);
16 }
17 va_end(var_arg);
18
19 return sum/n_values;
20 }
21
22  void main()
23 {
24 cout<<"1,2,3的平均值为:";
25 cout<<average(3,1,2,3)<<endl;
26
27 cout<<"1,2,3,4的平均值为:";
28 cout<<average(4,1,2,3,4)<<endl;
29
30 cout<<"1,2,3,4,5,6,7,8,9,10)的平均值为:";
31 cout<<average(10,1,2,3,4,5,6,7,8,9,10)<<endl;
32 }

参考文献:《C和指针》

转载于:https://www.cnblogs.com/strider/articles/2052126.html

可变参数函数的一个简单例子相关推荐

  1. 可变参数函数——以printf为例子

    一. 调用形式 void foo(int argv1, char argv2, -) 在参数表的末尾给出省略号,表明这个函数的参数是可变的 二. 工作原理 进程在调用函数时,会将函数参数压入用户栈,压 ...

  2. 关于C语言可变参数函数的一些研究和总结

    可变参数函数是指函数参数的个数.类型等是不固定的,需要在用户调用过程中,根据实际传入的参数来确定其类型.个数等信息.例如:可变参数函数printf可谓是在C开发过程中使用最多的标准输出库函数之一,因此 ...

  3. C语言可变参数函数_初探

    一.什么是可变参数函数 C语言允许定义参数数量可变的函数,这称为可变参数函数(variadic function).这种函数需要固定数量的强制参数,后面是数量可变的可选参数. 其中,强制参数必须至少一 ...

  4. 揭密X86架构C可变参数函数实现原理

    前两天公司论坛有同事在问C语言可变参数函数中的va_start,va_arg 和 va_end 这些接口怎么实现的?我毫不犹豫翻开箱底,将多年前前(算算有十年了)写的文章「亲密接触C可变参数函数」发给 ...

  5. c语言中函数名可变,C语言中可变参数函数

    转帖两封: 首先在介绍可变参数表函数的设计之前,我们先来介绍一下最经典的可变参数表printf函数的实现原理. 一.printf函数的实现原理 在C/C++中,对函数参数的扫描是从后向前的.C/C++ ...

  6. #{}不自动改参数类型_【Just For Fun】C - 可变参数函数、可变参数宏 __VA_ARGS__、额外的逗号

    [Just For Fun] 本系列纯粹娱乐.研究用.一些旁门左道的东西. 事实上可能完全没用. (๑•̀ω•́๑) 對於可变参数函数.可变参数宏 __VA_ARGS__ , 我曾經有在另一些地方寫過 ...

  7. 解析可变参数函数的实现原理(printf,scanf)

    From: http://hi.baidu.com/huifeng00/blog/item/085e8bd198f46ed3a8ec9a0b.html 学习C的语言的时候,肯定接触到标准输出和标准输入 ...

  8. 从printf谈可变参数函数的实现

    作者:戎亚新 摘要:一直以来都觉得printf似乎是c语言库中功能最强大的函数之一,不仅因为它能格式化输出,更在于它的参数个数没有限制,要几个就给几个,来者不拒.printf这种对参数个数和参数类型的 ...

  9. mysql不定参数函数_可变参数函数(一)

    一个函数可以接受不定数的参数个数,这就是可变参数函数,比较常见的比如printf(),scanf(): printf(const char*format,-); printf("%d&quo ...

最新文章

  1. 腾讯AI单挑碾压王者荣耀职业玩家:人类15场只能赢1局,坚持不到8分钟 | “绝悟”技术细节披露...
  2. 数据结构源码笔记(C语言):哈夫曼树
  3. CLR查找和加载程序集的方式(二) 流程图
  4. Python turtle库绘制奥运五环
  5. Linux Hung Task分析
  6. 云计算实战系列十五(SQL I)
  7. bert获得词向量_只需几行 Python 代码,即可用 BERT 玩转词嵌入!
  8. fixed定位之后,如何让div上下垂直居中
  9. PageHelper测试分页插件
  10. 监狱智能化管理系统综合安防解决方案
  11. pdf编辑器哪个好 怎么添加pdf文件水印
  12. 接口 常见视频接口详解
  13. javascript继承的6种方法
  14. f452虚拟服务器,F460 F452 获取超级密码 解决 LOID 注册断线 保留telnet 无需ttl 不用拔光纤...
  15. 解除Windows 10休眠时自动唤醒设置
  16. azkaban 安装
  17. 【2】Kali破解家用WI-FI密码 - WPA/WPA2加密
  18. 三分钟看完京东区块链白皮书
  19. 计算机一级重点知识,计算机一级考试重点
  20. 新玺配资:股票波段操作中的操作法则

热门文章

  1. 浅谈Vue中的虚拟DOM
  2. 简单入门Buffer
  3. html实现点赞效果,js实现点赞效果
  4. 考虑空气阻力的抛射体的matlab,考虑空气阻力的抛射体运动mtlab仿真
  5. php clearinterval,JavaScript定时函数(2)setInterval与clearInterval
  6. python自动化测试学习有用吗_python自动化测试学习-UnitTest/PyUnit的用法介绍
  7. java 点击一下左边按钮_右边显出一列表_举个例子_java椭圆按钮怎么设置,最好举一个简单的例子,只要有窗体中一个椭圆按钮就可以,最好有注释,谢谢,好的...
  8. 20200827:2020力扣第33周双周赛题解
  9. 闽南师范大学计算机学院研究生,闽南师范大学计算机学院2019考研调剂信息
  10. java中的命名空间_XPath与Java中的命名空间