可变参数:stdarg.h

作者:追风剑情 发布于:2020-3-23 17:27 分类:C

stdarg.h头文件提供一种方法定义参数数量可变的函数。这种函数的原型有一个形参列表,列表中至少有一个形参后面跟有省略号:

void f1(int n, ...) //有效
int f2(int n, float x, int k, ...) //有效
double f3(...) //无效

在下面的表中,parmN是省略号前面的最后一个形参的标识符。在上面的例子中,第1种情况的parmN为n,第2种情况的parmN为k。

头文件中声明了va_lis类型表示储存形参列表中省略号部分的形参数据对象。下面列出了3个带可变参数列表的函数中用到的宏。在使用这些宏之前要声明一个va_list类型的对象。

可变参数列表宏
描述
void va_start(va_list ap, parmN) 该宏在va_arg()和va_end()使用ap之前初始化ap,parmN是形参列表中最后一个形参名的标识符
void va_copy(va_list dest, va_list src) 该宏把dest初始化为src当前状态的备份(C99)
type va_arg(va_list ap, type) 该宏展开为一个表达式,其值和类型都与ap表示的形参列表的下一项相同,type是该项的类型。每次调用该宏都前进到ap中的下一项
void va_end(va_list ap) 该宏关闭以上过程,可能导致ap在再次调用va_start()之前不可用
void va_copy(va_list dest, va_list src) 该宏把dest初始化为src当前状态的备份(C99)

变参函数比使用变参宏更复杂,但是函数的应用范围更广。

示例:


  1. #define _CRT_SECURE_NO_WARNINGS
  2. #include <stdio.h>
  3. #include <stdlib.h>
  4. #include <stdarg.h>
  5.  
  6. double sum(int, ...);
  7.  
  8. int main(int argc, char* argv[])
  9. {
  10. double s, t;
  11.  
  12. s = sum(3, 1.1, 2.5, 13.3);
  13. t = sum(6, 1.1, 2.1, 13.1, 4.1, 5.1, 6.1);
  14. printf("return value for "
  15. "sum(3, 1.1, 2.5, 13.3): %g\n", s);
  16. printf("return value for "
  17. "sum(6, 1.1, 2.1, 13.1, 4.1, 5.1, 6.1): %g\n", t);
  18.  
  19. system("pause");
  20. return 0;
  21. }
  22.  
  23. double sum(int lim, ...)
  24. {
  25. va_list ap; // 声明一个对象储存参数
  26. //va_list apcopy;
  27. double tot = 0;
  28. int i;
  29.  
  30. va_start(ap, lim); // 把ap初始化为参数列表
  31. //va_arg()不提供退回之前参数的方法,所以有必要保存va_list类型变量的副本
  32. //va_copy(apcopy, ap);
  33. for (i = 0; i < lim; i++)
  34. {
  35. tot += va_arg(ap, double); // 访问参数列表中的每一项
  36. }
  37. va_end(ap); // 清理工作
  38. //调用了va_end(ap)后,只有用va_start(ap, lim)重新初始化ap后,才能使用变量ap
  39.  
  40. return tot;
  41. }


运行测试

111.png

标签: C语言

Powered by emlog  蜀ICP备18021003号-1   sitemap

川公网安备 51019002001593号