可变参数列表源码剖析
本文将剖析可变参数列表实现原理
average函数可利用可变参数列表实现对未知参数的平均值求解
int average(int n,...)
{va_list arg;
int i=0;
int num =0;
va_start(arg,n);
for(i=0;i<n;i++)
{
num+=va_arg(arg,int);
}
va_end(arg);
return num/n;
}
int main()
{
average(5,1,2,3,4,5);
return 0;
}
1 typedef char * va_list;
typedef :类型重命名
此操作为类型重命名,将 char * 命名为 va_list,实际上va_list 就是char *.
2. va_start(arg,n);
源码为: (arg =(va_list)&n + INTSIZEOF(n))
(va_list)&n : (char *)&n,将n的地址得到,强转为char *类型
INTSIZEOF(n) : 向上取整,如 当n的类型大小为1,2,3时,该宏等于4,n的类型大小为5,6,7时,该宏等于8
作用:使arg指向可变列表的第一个,因为参数压栈是从右往左,地址是从高到低
3, va_arg(arg,int);
源码为: (*(int *) ( (arg+=INTSIZEOF(int) ) - INTSIZEOF(int) )
(arg+=INTSIZEOF(int) ) : 使arg指向可变列表的下一个参数,为下次循环做准备(巧妙之处);
( (arg+=INTSIZEOF(int) ) - INTSIZEOF(int) ) : 使整体指向原本参数
作用: 可循环拿到可变参数,每使用一次就会向后刷新
4, va_end(arg);
源码为; (arg=(va_list)0)
作用 ; 使arg指针指向NULL