转自:http://www.cnblogs.com/jerrychenfly/archive/2010/10/22/1858232.html

下面,我们来看一下,如果在c++的函数中接收数量不定的函数参数。这种形式如同在C#的函数参数列表中使用params 类型的参数。

  我们可以将函数定义成能够接受任意数量的实参。通过将省略号(3个句点...)写在函数定义中形参列表的最后,即可表示调用该函数时可以提供数量可变的实参。例如:

  int sumValues(int first,...)

  {

    //Code for the function

  }

  函数定义中必须至少有一个普通形参,但也可以有多个。省略号必须总是放在形参列表的最后。

  显然,定义中没有关于可变列表中实参的类型或数量的任何信息,因此我们的函数代码必须弄清楚自己被调用时接收的是什么。本地C++库在stdarg.h头文件中定义了va_start、va_arg、和va_end宏,以帮助我们做这件事。用示例来说明其用法是最容易的。

  

  

  #include <iostream>
  #include "stdarg.h"

  using namespace std;

  int sum(int count,...)
  {
     if(count<=0)
        return 0;
     va_list arg_ptr;
     va_start(arg_ptr,count);

    int sum = 0;
     for (int i=0;i<count;i++)
     {
        sum+=va_arg(arg_ptr,int);
     }
     va_end(arg_ptr);
     return sum;
    }

  int main()
  {

    cout<<sum(2,4,6,8,10,12)<<endl;
     cout<<sum(2,22,33,44,55,66,77,88,99)<<endl;
     return 0;
  }

  本例结果:

    10

    55

    按任意键继续。。。

  示例说明

   main()函数函数在两条输出语句中调用了sum()函数,第一次有6个实参,第二次有9个实参。

  sum()函数有一个int类型的普通形参,它表示后面跟着的实参的数量。形参列表中的省略号表明可以传递任意数量的实参。基本上,我们有两种方法来确定调用该函数时有多少实参:第一是像sum()函数一样,用某个固定的形参指定实参的数量;第二是要求最后一个实参具有特殊的标记值,以便我们进行检查和确认。

  为了开始处理可变的实参列表,我们首先声明一个va_list类型的指针:

  va_list arg_ptr;

  va_list 类型是在stdarg.h头文件中定义的,该指针用来依次指向各个实参。

  va_start宏用来初始化arg_ptr,使其指向列表中的第一个实参:

  va_start宏用来初始化arg_ptr,使其指向列表中的第一个实参:

  va_start(arg_ptr,count);

  这个宏的第二个实参是函数形参列表中活力号前面固定形参的名称,用来确定第一个可变实参的位置。

  我们在for循环中取出列表中各个实参的值:

  for (int i=0;i<count;i++)
   {
      sum+=va_arg(arg_ptr,int);
   }

  var_arg宏返回arg_ptr指向的位置存储的实参值,并使arg_ptr递增,以指向下一个实参值。va_arg宏的第二个实参是第一个实参的类型,决定着我们得到的数值以及va_arg递增的方式,因此如果该实参不正确,将造成混乱。程序也许会执行,但我们得到的数值将是无用数据,而且arg_ptr将被错误地递增,从而指向另外的无用数据。

  当结束检索实参值之后,我们用下面这条语句使arg_ptr复位:

  va_end(arg_ptr);

  va_end宏将我们传递给它的实参--va_list类型的指针复位成空值。始终这样做是个好主意,因为在处理过实参之后,arg_ptr将指向某个不包含有效数据的存储单元。

C++ 不定参数(转)的更多相关文章

  1. golang中不定参数与数组切片的区别

    package main import "fmt" func main() { myfunc1(, , , ) //传递不定数量的参数 myfunc2([], , , }) //传 ...

  2. 深入浅出ES6(五):不定参数和默认参数

    作者 Jason Orendorff  github主页  https://github.com/jorendorff 不定参数 我们通常使用可变参函数来构造API,可变参函数可接受任意数量的参数.例 ...

  3. C技巧:结构体参数转成不定参数

    下面这段程序是一个C语言的小技巧,其展示了如何把一个参数为结构体的函数转成一个可变参数的函数,其中用到了宏和内建宏"__VA_ARGS__",下面这段程序可以在GCC下正常编译通过 ...

  4. 不定参数函数原理以及实现一个属于自己的printf函数

    一.不定参数函数原理 二.实现一个属于自己的printf函数 参考博文:王爽汇编语言综合研究-函数如何接收不定数量的参数

  5. C语言函数不定参数实现方式

    函数如何实现不定参数: 由于在C语言中没有函数重载,解决不定数目函数参数问题变得比较麻烦,即使采用C++,如果参数个数不能确定,也很难采用函数重载.对这种情况,提出了指针参数来解决问题. (1)va_ ...

  6. [js高手之路] es6系列教程 - 不定参数与展开运算符(...)

    三个点(...)在es6中,有两个含义: 用在形参中, 表示传递给他的参数集合, 类似于arguments, 叫不定参数. 语法格式:  在形参面前加三个点( ... ) 用在数组前面,可以把数组的值 ...

  7. SE6 不定参数和默认参数详解和使用细节

    在SE5以前我们通常通过arguments类数组对象来引用不定形参,SE6则使用了一种叫做不定参数的写法,比起隐式的arguments要直观的多. 不定参数使用...参数名来指定一个不定参数,参数名指 ...

  8. dataframe的select传入不定参数

    在提取 dataframe 里面的列时,需要传入不定参数,即 dataframe.select(args) .例如某个 dataframe 如下: 一般提取某列或者某几列的时候是这样子写的: data ...

  9. 不定参数对arguments对象的影响

    如果声明函数时定义了不定参数,则在函数被调用时,arguments对象包含了所有传入的参数: function checkArgs(...args){ console.log(args.length, ...

  10. 深入浅出ES6:不定参数和默认参数

    不定参数 我们通常使用可变参函数来构造API,可变参函数可接受任意数量的参数.例如,String.prototype.concat方法就可以接受任意数量的字符串参数.ES6提供了一种编写可变参函数的新 ...

随机推荐

  1. Oracle数据库中插入日期型数据(to_date的用法)(转载)

    往Oracle数据库中插入日期型数据(to_date的用法) INSERT  INTO  FLOOR  VALUES  ( to_date ( '2007-12-20 18:31:34' , 'YYY ...

  2. c#常用快捷键

    VS快捷键大全(总结了一些记忆的口诀) 原文转载至   https://www.cnblogs.com/liyunhua/p/4537054.html#top  谢谢大牛的分享!     相信.Net ...

  3. collections --Counter

    collections 模块--Counter 目的是用来跟踪值出现的次数.是一个无序的容器类型,以字典的键值对形式存储,其中元素为 key,其计数作为 value.计数值可以是任意的 Integer ...

  4. HashMap与ConcurrentHashMap

    从JDK1.2起,就有了HashMap,正如前一篇文章所说,HashMap不是线程安全的,因此多线程操作时需要格外小心. 在JDK1.5中,伟大的Doug Lea给我们带来了concurrent包,从 ...

  5. 一图看懂java内存模型

    熟话说一张好图胜过千言万语,在此便将java内存模型重新整理了一次,将细节标注到图中献给需要的同学:

  6. SQL语言的分类

    本文转自https://www.cnblogs.com/fjfzhkb/archive/2007/10/18/929108.html SQL语言共分为四大类:数据查询语言DQL,数据操纵语言DML, ...

  7. SpringMVC RequestMapping注解

    1.@RequestMapping 除了修饰方法,还可以修饰类 2.类定义处:提供初步的请求映射信息.相对于WEB应用的根目录  方法处:提供进一步细分映射信息  相对于类定义处的URL.若类定义处未 ...

  8. jenkins的搭建

    根据官方网站的步骤进行安装 网址:https://wiki.jenkins.io/display/JENKINS/Installing+Jenkins+on+Red+Hat+distributions ...

  9. UML中类图的一些基本知识

    一.类 类(class)封装了数据和行为,是面向对象的重要组成部分,他是具有相同操作.属性.关系的对象集合的总称. 在软件运行时,类被实例化成对象(object),对象对应某个具体的事物,是类的实例( ...

  10. 五分钟学习React(四):什么是JSX

    JSX,即javscript XML,是js内定义的一套XML语法.目前是使用babel作为JSX的编译器.这也是在前几期中载入babel的原因. Facebook引入JSX是为了解决前端代码工程复杂 ...