可变参数原理
由于函数参数是存放在栈中的,printf函数有__cdecl声明,所以是是从右到左依次入栈(栈地址是由高地址向低地址生长的c函数参数入栈顺序,所以参数的地址从左到右依次增大),从右到左依次初始化,所以,函数的参数位置是确定的,一旦我们知道了某一个参数的地址我们就可以获得所有参数的地址。
va_start
va_end
va_arg
printf实现
//__CRTDECL 声明参数由右向左入栈
void __CRTDECL MyPrint(const char* format, ...)
{
va_list ap;
va_start(ap, format);
while (auto c = *format)
{
if (c == '%')
{
switch (*(++format))
{
case 'c':
cout << va_arg(ap, char);
break;
case 'd':
cout << va_arg(ap, int);
break;
case 'f':
cout<< va_arg(ap, double);
break;
case 's':
cout << (char*)va_arg(ap, char*);
break;
default:
break;
}
}
else
{
cout << c;
}
++format;
}
va_end(ap);
}
MyPrint("c:[%c], d:[%d], s:[%s], f:[%f]\n", 'a', 22, "str", 22.3);