在我们使用函数时,一般大多数情况下里面的参数都是给定的,而且我们一般使用时并不会超过三个参数,可是这并不排除不会出现三个以上的参数,比如说求平均值,求和等等一些可能出现三个以上参数的函数运算,这时我们的参数不再是固定的,而是随时会不断变化的。因此我们就需要一种方法来实现它们,这种方法就是C语言给我们提供的一种叫做可变参数列表的函数方法。
首先,可变参数列表是通过宏来定义的,而这些宏又在<stdarg.h>的头文件中,因此我们在使用时要先引用该头文件,在引用后我们需要其下三个宏的函数:
void va_start(va_list ap, last); type va_arg(va_list ap, type); void va_end(va_list ap);
上面这三个函数都是用宏定义的,下面是这些宏在标准ANSI形式下的定义:
typedef char * va_list; #define _INTSIZEOF(n) ( (sizeof(n) + sizeof(int) - 1) & ~(sizeof(int) - 1) ) #define va_start(ap,v) ( ap = (va_list)&v + _INTSIZEOF(v) ) #define va_arg(ap,t) ( *(t *)((ap += _INTSIZEOF(t)) - _INTSIZEOF(t)) ) #define va_end(ap) ( ap = (va_list)0 )
从上面的宏我们可以看出:
va_list实际上是一个字符类型的指针。
_INTSIZEOF()这个函数主要是把传进来n的长度变成int长度的整数倍。
va_start主要作用是将va_list定义的指针指向v后面的地方,也就是可变参数第一个数的首地址,实际上就是对va_list进行初始化。
va_arg则是将当前参数取出并将va_list定义的指针变量指向下一个参数,t指的是参数类型。
va_end是对整个参数列表进行清理或者也可理解为释放。
下面通过一个简单的例子看下具体的实现方法---通过可变参数列表实现求多个数的最大值
#include<stdarg.h> int MAX(int count,...) { int i=0; int max=0; int k=0; va_list arg; //定义一个va_list类型的变量 va_start(arg,count); //让arg指向count后面第一个可变参数,进行初始化 max=va_arg(arg,int); //将第一个可变参数取出,并指向下一个可变参数 for(i=0;i<count-1;i++) { k=va_arg(arg,int); //通过count依次取出 if(k>max) //进行比较 max=k; } va_end(arg); //进行清理释放 return max; }
这就是C中可变参数的用法,我们的printf,scanf等都是通过它们实现的,当然有一点要注意的是可变参数列表可接受多个参数,但至少需要一个参数。
原文地址:http://cuiyuxuan.blog.51cto.com/10786939/1718828