the c book :Variable numbers of arguments(可变参数)

2014-03-10 21:40 仅出于方便使用的目的,错误不可避免,请见谅。

翻译自:the c book : variable number of arguments


  • 经常需要实现这样一种函数:参数个数未知或者参数个数不确定,比如printf。下面的例子将展现此类函数的声明/定义及使用。
            int f(int , ……);
            int f(int,……) {……};
            int g() { f(1,2,3);}
  • 如何访问可变参数?
          需要包含头文件<stdarg.h>。其中,引入了一种新的类型va_list,同时声明了va_start,va_arg,var_end。
  void va_start(va_list ap, parmN);
  type va_arg(va_list ap, type);
  void va_end(va list ap);
首先,需要使用va_start宏来初始化ap,以便接下来供va_arg和va_end来使用。va_start的第二个参数,即parmN是可变参数函数声明中最右边的 已命名形成变量标识符(在‘……’之前的变量标识符)。注意:parmN不可以是:register存储类型变量,函数,数组类型。
其次,ap初始化以后,可以通过va_arg宏来访问参数。每一次调用va_arg都会从参数列表中抽取出“下一个参数”,并以指定类型返回该参数。如果“下 一个参数”不是指定类型的变量,这行为未定义。
需要注意避免由“算术转换arithmetic conversions”带来的问题。使用char或者short作为va_arg的第二参数,不可避免的招致错误,因为这些类型,通常会被“提升“至signed int 或者unsigned int;同样地,float将会被转换为double。
注意,对于类型charunsigned char,unsigned   short 和 unsigned bitfields都将被“提升”至 unsigned int。
对于没有更多的参数可用时,调用va_arg将导致未定义行为。
参数type需满足这样的要求:通过附加一个*,即可转换为相应类型的指针类型。比如,char附加*后,即为char *;char []就不能满足要求。

       

        最后,当所有参数都被处理结束后,需要调用va_end,以避免va_list被继续使用,若是没有使用va_end,则会有未定义行为。

        整个 参数列表,在再次调用va_start后,可以被再次重新遍历使用。


/*just a demo*/

#include <stdlib.h>
#include <stdarg.h>
#include <stdio.h>

int maxof(int,int, ...) ;
void f(void);

int main()
{
        f();
        exit(EXIT_SUCCESS);//cstdlib中定义的宏
}

int maxof(int aa,int n_args, ...)
{
        register int i;
        int max, a;
        va_list ap;

        va_start(ap, n_args);       
        max = va_arg(ap, int);//获取n_args后的第一个参数
        printf("%d\n",max);
        for(i = 2; i <= n_args; i++) {
                if((a = va_arg(ap, int)) > max)
                        max = a;
        }

        va_end(ap);
        return max;
}


void f(void) 
{
        int i = 5;
        int j[256];
        j[42] = 1;
        printf("%d\n",maxof(1,3, i, j[42], 0));

}



  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值