码迷,mamicode.com
首页 > 其他好文 > 详细

可变参数函数

时间:2014-10-01 13:26:51      阅读:210      评论:0      收藏:0      [点我收藏+]

标签:blog   http   使用   ar   for   数据   sp   div   art   

http://blog.csdn.net/ithzhang/article/details/7021317

变长参数的函数即参数个数可变、参数类型不定 的函数。

最常见的例子是printf函数、scanf函数和高级语言的Format函数。在C/C++中,为了通知编译器函数的参数个数和类型可变(即是不定的、未知的),就必须以三个点结束该函数的声明。

// printf函数的声明

int printf(const char * _Format, ...);

//scanf函数声明

int scanf(const char * _Format, ...);

//自定义变长参数函数func的声明

int func(int a,int b,...);

  在C/C++中,任何使用变长参数声明的函数都必须至少有一个指定的参数(又称强制参数),即至少有一个参数的类型是已知的,而不能用三个点省略所有参数的指定,且已知的指定参数必须声明在函数最左端

//下面这种声明是非法的  
  
int func(...);//错误  
  
int func(...,int a);//错误  

  

  1. 因为C语言压栈顺序为从右到左。
  2. 栈的扩展方向是向下扩展,所以栈底为高地址,栈顶为低地址。

    比如假设f(a,b,c,d)按照从右到左压栈,那么d应该是第一个进栈的,a是最后一个进栈的,所以d的地址应该比a的高。所以通过递增地址的办法可以得到下一个参数、、

因此参数与参数之间是相邻的,知道前一个参数的类型及地址,根据后一个参数的类型就可以获取后一个参数的内容

 

 

 

//访问可变参数流程  
  
va_list args; //定义一个可变参数列表  
  
va_start(args,arg);//初始化args指向强制参数arg的下一个参数;  
  
va_arg(args,type);//获取当前参数内容并将args指向下一个参数  
  
...//循环获取所有可变参数内容  
  
va_end(args);//释放args  

  

//sum为求和函数,其参数类型都为int,但参数个数不定  
//第一个参数(强制参数)n指定后面有多少可变参数  
int sum(unsigned int n,...)  
{  
   int sum=0;  
   va_list args;  
   va_start(args,n);  
   while(n>0)  
   {  
    //通过va_arg(args,int)依次获取参数的值  
     sum+=va_arg(args,int);  
     n--;  
   }  
   va_end(args);  
   return sum;  
}  

  

 上面这段代码经测试可以正常输出。也就是说,我们通过使用指针,实现了参数不定的函数。但这里还有一个问题,就是sum函数的所有参数都是int类型的,事先我们知道要移动sizeof(int)位的指针,可是如果参数类型不同呢?

 答案与分析:这的确是个比较麻烦的问题,因为不同的数据类型占用的字节数可能是不一样的(如double型为8个字符,short int型为2个),所以很难事先确定应该移动多少个字节!但是办法还是有的,这就是使用指针了,无论什么类型的指针,都是占用4个字节,所以,可以把所有的传如入参数都设置为指针,这样一来,就可以通过移动固定的4个字节来实现遍历可变参数的目的了,至于如何取得指针中的内容并使用他们,当然也是无法预先得知的了。所以这大概也就是像printf(),scanf()之类的函数还需要一个格式控制符的原因吧

可变参数函数

标签:blog   http   使用   ar   for   数据   sp   div   art   

原文地址:http://www.cnblogs.com/notlate/p/4003146.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!