C语言_可变参数列表解析

来源:互联网 发布:空间和域名 编辑:程序博客网 时间:2024/06/06 03:27

     在自定义函数时,例如int fun(int a,int b)的传参都是固定个数的,那么如何自定义一个可传自定义个参数的函数呢?首先我们可以参照printf()函数的定义。
     printf(char* format,…);“…”表示参数列表未确定的部分,而列表里最少要有一个确定的参数,即可以是fun(int a,int b,…); 但不可以fun(…);
     在函数内部代码上,如何实现对不确定部分参数的访问和使用?如果能解决这个问题,那么就解决了传自定义个参数的函数的定义。
     解决这个问题,首先要理解函数的栈帧结构,理解形参在内存中如何存储。栈帧结构可以参见博主上一篇博文C语言_函数栈帧
      比如要定义一个求平均值的函数fun();可以传n个数,求这n个数的平均值。我们可以这样int fun(int n,…);f当我我们这样使用fun()函数时,fun(n,a,b,c)栈帧结构如下:
      fun(n,a,b,c)
      形参是从右往左依次压栈的,所以c在高地址,n在最下面,当我们取到n的地址和n的参数类型时,就能取到a的地址,int *p=&n,a的地址就是p+1;同理可以得到b和c的地址。
     

int fun(int n,..){    int num=0;    int *p=&n;    int i=0;    for(i=0;i<n;i++)    {    num+=*(p+i);    }    return num/n;}

除了这个方法,还可以使用宏va_list,声明一个变量va_list arg,arg就用于访问可变参数列表不确定部分。首先用va_start(arg,n)初始化arg,使arg指向可变参数的第一个参数,int x1=va_arg(arg,int)把第一个参数以int类型赋值给x1,arg就会自动指向下一个参数,访问完毕之后还需要调用宏va_end(),用va_end(arg)结束。

int fun(int n,...) {   int num=0;   int i=0;   va_list arg;   va_start(arg,n);   for(i=0;i<n;i++)   {   num+=va_arg(arg,int);   }   va_end(arg);   return num/n;

   像这样使用宏的方法,同样可以实现对可变参数列表的访问。

原创粉丝点击