如何创建一个可变参数函数

     在初学C语言阶段,我们会学到如何创建一个函数,但通常我们创建的函数的参数是有限的,有没有可能可以创建一个参数数量可以不受限制的函数呢?答案是有的,但是存在一些限制。C语言提供了一个很有趣的方式,可以实现把函数写成可变参数的形式,可以使得函数能够接受1个以上的任意多个函数。

       请看下面这个函数:

int Max(int n, ...)
{
	va_list arg;
	int i = 0;
	int max = 0;
	int j = 0;
	va_start(arg, n);
	max = va_arg(arg, int);
	for (i = 0; i < n-1; i++)
	{
		j = va_arg(arg, int);
		if (max < j)
		{
			max = j;
		}
	}
	return max;
}

       这是一个求一串数字最大值的函数,在这里参数是可变的。接下来我们开始讨论它是如何变成可变参数的。要知道,可变列表是通过宏来实现的,这些宏定义与stdarg.h头文件,是标准库的一部分。这个头文件包含了一个变量类型和三个宏,分别为 va_list, va_strat, va_arg, va_end。首先注意参数列表中的省略号:它提示此处可能传递数量和类型未确定的参数。在函数开始的时候,函数先声明了一个变量arg,这个变量是用来访问参数列表中未确定的部分,被定义成char *类型,由va_start来初始化。va_start 的第一个参数是va_list变量的名字,第二个参数是省略号前最后一个有名字的参数,而初始化的过程就是把arg变量设置为指向可变参数的第一个参数。
    当使用va_arg访问参数时,需要传递两个参数,va_list变量和参数列表中要访问的参数类型,然后va_arg返回参数的值,并使arg指向下一个参数。当访问结束后,调用va_end。

        下面是这几个宏的定义:
 

#define _INTSIZEOF(n) ((sizeof(n) + sizeof(int) - 1) & ~(sizeof(int) - 1))
#define __crt_va_start_a(ap, v) ((void)(ap = (va_list)_ADDRESSOF(v) + _INTSIZEOF(v)))
#define __crt_va_arg(ap, t) (*(t*)((ap += _INTSIZEOF(t)) - _INTSIZEOF(t))) #define __crt_va_end(ap) ((void)(ap = (va_list)0))

          上文提到,可变列表是通过宏来实现的。所以,如果将这些宏定义带入上面的程序中,会得到同样的结果。不过,这个方法是有一些限制的,下面是运用该方法时需要注意的地方:
          1.可变参数必须从头到尾挨个访问,如果你要在访问一些后停止是可以实现的,但不能选择一开始访问中间的几个变量。

          2.参数列表中至少有一个命名的参数,如果没有,就无法初始化。

          3.以上这些宏是无法直接识别参数的数量的,而且也无法判断参数的类型。
      4.不要在va_arg中指定错误的类型。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值