可变参数列表

测试环境: vs2008

1、可变参数列表

为什么需要可变参数呢?
在函数原型中,列出了函数期望接受的参数,原型只能显示固定数目的参数,如果函数原型列出的参数与可调用参数不匹配或数目不一样,程序将无法运行。例如,我们想要求一系列值的平均值,这里的一系列的数目是不确定的,如果这些值存储于数组中,这个任务就很简单了,但如果我们不用数组,想要直接调用,就需要可变参数了。
什么是可变参数?
C语言中的可变参数是通过将函数是按为可变参数的形式,可以是得函数接受一个以上的任意多个参数(不固定)。

2、stdarg宏

可变参数列表是通过宏来是实现的,这些宏定义于 stdarg.h 有文件,这个有文件声明了三个宏———— va_start, va_arg和va_end,和一个类型 va_list。

#elif   defined(_M_IX86)

#define _INTSIZEOF(n)   ( (sizeof(n) + sizeof(int) - 1) & ~(sizeof(int) - 1) )

#define _crt_va_start(ap,v)  ( ap = (va_list)_ADDRESSOF(v) + _INTSIZEOF(v) )
#define _crt_va_arg(ap,t)    ( *(t *)((ap += _INTSIZEOF(t)) - _INTSIZEOF(t)) )
#define _crt_va_end(ap)      ( ap = (va_list)0 )
3、可变参数三个宏的使用
初始化

函数声明了一个名叫 va_arg 的变量, 它用于访问未确定的部分,这个变量通过 va_start 来初始化。
它的里边有两个参数:
1、va_list变量的名字
2、省略号前最后一个有名字的参数。
初始化时把va_arg变量设置为可变参数部分的第一个参数。

访问后边参数

这里需要 va_arg ,va_arg返回这个参数的值,并使用 va_arg指向下一个可变参数。
它的里边也有两个参数:
1、va_list变量
2、参数列表中下一个参数的类型

用va_end宏来释放此前动态分配的内存
4、看一个例子

接下来我们来看一个例子来理解下可变参数的用法。

//求任意个参数的平均值

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


int Max(int n_values, ...)
{
    va_list va_arg;       
    int count = 0;
    int tmp = 0;
    int max = 0;

    va_start( va_arg, n_values);    //初始化
    for(count=0; count<n_values; count++)
    {
        if( (tmp =va_arg(va_arg, int))> max )      //添加取自可变参数列表的值
        {
            max = tmp;
        }
    }

    return max;
}

int main()
{
    int n_values = 0;
    int v1 = 2; int v2 = 3; int v3 = 5;int v4 = 10;
    int max1 = 0; int max2 = 0;

    max1 = Max(3, v1, v2, v3);
    max2 = Max(4, v1, v2, v3, v4);
    printf("max1 = %d, max2 = %d\n", max1, max2);

    return 0;
}
5、可变参数的限制

可变参数必须从头到尾逐个访问,如果你在访问了几个可变参数之后想半途终止,这是可以的,但是,如果你想一开始就访问列表中间的参数,那是不行的。
* 参数列表中至少有一个命名参数。如果连一个命名参数都没有,就无法使用va_start
* 这些宏是无法直接判断实际存在参数的变量。
* 这些宏无法判断每个参数的是类型。
* 如果在 va_arg 中指定了错误的类型,那么其后果是不可预测的。
这里写图片描述

可变参数的创建是先开辟一块空间,创建好最右边的变量之后,然后在根据类别有上往下创建,因此不能直接访问中间变量,可以访问一半终止。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值