C可变参数学习
2019-06-19 本文已影响0人
水清波
int sum(int cnt, ...){
va_list vl;
va_start(vl, cnt);
int tmp, sum = 0;
for (int i = 0; i < cnt; i++)
{
tmp = va_arg(vl, int);
sum += tmp;
}
va_end(vl);
return sum;
}
源码分析
typedef char * va_list;
va_list是个char指针
#define _crt_va_start(ap,v) ( ap = (va_list)_ADDRESSOF(v) + _INTSIZEOF(v) )
#define _INTSIZEOF(n) ( (sizeof(n) + sizeof(int) - 1) & ~(sizeof(int) - 1) )
#define _ADDRESSOF(v) ( &reinterpret_cast<const char &>(v) )
ap获取了v的地址,并跳过v的长度,指向了后一个单位
#define _crt_va_arg(ap,t) ( *(t *)((ap += _INTSIZEOF(t)) - _INTSIZEOF(t)) )
ap跳过v大小并返回前一个单位的地址,转为t的类型,获得内容
#define _crt_va_end(ap) ( ap = (va_list)0 )
ap制空,结束
sprintf也是类似的规则,但是底层源码是库源码。
可以参考别人的 自适应 sprintf源码
https://blog.csdn.net/echoisland/article/details/6086406