可变参数列表源码的剖析
首先下面是使用可变参数列表来实习求多个参数的最大值的代码:
#include <stdio.h>
#include <stdarg.h>
int Max(int n,...)
{
va_list arg;
int i = 0;
int max = 0;
va_start(arg,n);
max = va_arg(arg,int);//取可变参数的部分的第一个值赋值给max
for(i=0; i<n-1; i++)
{
//取可变参数的部分的第一个参数的值,之后指向下一个
int tmp = va_arg(arg,int);
if(max<tmp)
{
max = tmp;
}
}
va_end(arg);
return max;
}
int main()
{
int ret = 0;
ret = Max(4,78,5,89,2);
printf("%d\n",ret);
return 0;
}
在定义Max函数中用到了可变参数“…”,这时就要提一下其中涉及的四个宏:
1. va_list
它的定义是:
typedef char * va_list;
即它等同于char *,用于定义变量
2. va_start(arg,n)
它的定义是:
#define va_start _crt_va_start
#define _crt_va_start(ap,v) ( ap = (va_list)_ADDRESSOF(v) + _INTSIZEOF(v) )
它的作用是让arg指向可变参数的部分的第一个值
3.va_arg(arg,int)
它的定义是:
#define va_arg _crt_va_arg
#define _crt_va_arg(ap,t) ( (t )((ap += _INTSIZEOF(t)) - _INTSIZEOF(t)) )
它的作用是取可变参数的部分的第一个参数的值,调用之后指向下一个参数的值
4.va_end(arg)
它的定义是:
#define va_end _crt_va_end
#define _crt_va_end(ap) ( ap = (va_list)0 )
它的作用是让arg变为空指针,防止生成野指针(指向一个已删除的对象或未申请访问受限内存区域的指针)