va_list : 用于定义遍历参数列表的指针
va_start : 让指针指向第一个参数
va_arg : 获取下一个参数, 并向后移动一个位置
va_end : 释放指针, 完成遍历
int 型参数列表
通过第一个参数控制参数个数法 :通过第一个参数确定输入参数的数量,多参函数无法确定参数个数。
void OutMoreArgn(int first,...)
{
va_list vArg;
va_start(vArg,first);
for(int i=0;i<first;i++)
{
int n=va_arg(vArg,int);
printf("%d\n",n);
}
va_end(vArg);
}
通过最后一个参数控制
void OutMoreArgn_end(int first,...)
{
va_list vArg;
va_start(vArg,first);
int n=first;
while(printf("%d\n",n)!=EOF&&(n=va_arg(vArg,int))!=-1);
va_end(vArg);
}
通过函数传递的原理,函数参数传递时是以栈的方式从右往左入栈,参数的存放形式按参数堆栈如f(a,b,c) a-->b-->c,所以理论上只要知道函数的任意一个参数,都可以通过指针移位的方式找到其他参数
void OutMoreArgn_funStack(int first,...)
{
int *a=&first;
for(int i=0;i<=first;i++)
{
printf("%d\n",*(a++));
}
}
格式化字符串型参数
void OutMoreArgStr_format(const char * fmt,...)
{
va_list vArg;
va_start(vArg,fmt);
char *p;
int n=_vscprintf(fmt,vArg);
p=(char*)malloc((n+1)*sizeof(char*));
vsprintf(p,fmt,vArg);
printf("%s",p);
va_end(vArg);
free(p);
}
自定义格式化参数
void OutMoreArgStr_S( char * fmt,...)
{
va_list vArg;
va_start(vArg, fmt);
while (*fmt)
{
if (*fmt == '%')
{
switch (*(++fmt))
{
case 'd': printf("%d",va_arg(vArg, int)); break;
case 'c': printf("%c",va_arg(vArg, char)); break;
case '?': printf("%c",va_arg(vArg, char)); break;
case '*': printf("%s",va_arg(vArg, char*)); break;
}
}
fmt++;
}
printf("\n");
va_end(vArg);
}