转自: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. vue.js之过滤器,自定义指令,自定义键盘信息以及监听数据变化

    一.监听数据变化 1.监听数据变化有两种,深度和浅度,形式如下: vm.$watch(name,fnCb); //浅度 vm.$watch(name,fnCb,{deep:true}); //深度监视 ...

  2. Linux第六节随笔 输入输出重定向 、管道、通配符、wc / grep / tr / sort / cut / which /whereis /locate /find /

    三期第五讲 -高级文件管理1.输入输出重定向 ls -l /dev/stdin -> /proc/self/fd/0 标准输入 设备:键盘 标记:0 ls -l /dev/stdout -> ...

  3. js控制图片自动缩放,实现铺满盒子,不变形,完全局中

    此js一般用于控制图片铺满盒子,但是比例不变,并且绝对局中原理:判断图片的高宽与盒子高宽的大小的关系,然后通过比例来控制图片的缩放及定位<!DOCTYPE html PUBLIC "- ...

  4. (转) Linux中profile、bashrc、bash_profile之间的区别和联系

    原文地址:http://blog.csdn.net/chenchong08/article/details/7833242 /etc/profile:此文件为系统的每个用户设置环境信息,当用户第一次登 ...

  5. 正则表达过滤表单隐藏元素,组装post数据

    <form name="form1" action="'.$serverUrl.'" method="post" > <i ...

  6. JS对时间的操作

    JS时间操作大全 1.获取每个月的开始和结束. 2.获取每个季度的开始和结束. 3.获取当前季度. 4.把日期转换为字符串(支持各种格式) ... 5.未完待续,不断添加 String.prototy ...

  7. PHP动态图像处理

    相关代码见:https://www.github.com/lozybean/learn_www/ 目录 1. 画布管理:     imagecreate():创建一个基于调色板的画布,指定画布的长.宽 ...

  8. commons-dbutils 字段名称转换

    我们在写bean的时候,字段通常都使用小驼峰命名法,但是在设计数据库时,一般使用下划线分割命名.这样,在取出数据库字段时,还需要转换.如何简洁的实现这种转换呢? 你能遇到的问题,只要是普遍存在的,大家 ...

  9. Python函数参数的五种类型

    之前项目需求,需要通过反射获取函数的参数,python中可以通过函数签名(signature)来实现. 首先需要了解函数参数的类型,Python的参数类型一共有5种:POSITIONAL_OR_KEY ...

  10. 通过渲染改变tabBarItem的背景图片

    p.p1 { margin: 0.0px 0.0px 0.0px 0.0px; font: 18.0px Menlo; color: #703daa } p.p2 { margin: 0.0px 0. ...