在可变参数列表中,我们在没有对应的参数表示符时,如何获取参数列表,在可变参数列表中我们,只有"...",所以通过标示符得到是不可能的,于是我们只好寻找另一种方式去获取,我们知道函数在调用时都会返回地址,参数,等压入到分配的栈空间中。参数的入栈顺序会取决于你的调用约定,如stdcall cd call fastcall等等,因此其实参数的顺序是有顺序的,va_start(va_list va,last)我们可以通过last参数的地址,从而访问其他的参数.其实va_list 本质上只是char*类型
1)typedef char * va_list;_list
2)#define _INTSIZEOF(n) ( (sizeof(n) + sizeof(int) - 1) & ~(sizeof(int) - 1) )
3)#define va_start(ap,v) ( ap = (va_list)&v + _INTSIZEOF(v) )
将最后一个参数的地址加上可变参数对其便宜后赋值给ap,即可变参数的首地址
4)#define va_arg(ap,t) ( *(t *)((ap += _INTSIZEOF(t)) - _INTSIZEOF(t)) )
指向下一个参数的地址
5)#define va_end(ap) ( ap = (va_list)0 )
#include <stdio.h>
#include <stdarg.h>
#include <string.h>
void translate(va_list va,const char *cmd);
void myprintf(const char *cmd,...);
int main()
{
myprintf("%s %d %c %f\n","aa",14,'b',3.14);
return 0;
}
void myprintf(const char *cmd,...)
{
va_list va;
va_start(va,cmd);
translate(va,cmd);
va_end(va);
}
void translate(va_list va,const char* cmd)
{
if('\0' == *cmd)
return;
if('%' != *cmd)
{
translate(va,cmd+1);
}
else
{
switch(*(cmd+1))
{
case 'd':case 'x':case 'c':
{
char buf[3] = "%";
buf[1] = *(cmd+1);
int value;
value = va_arg(va,int);
printf(buf,value);
}
break;
case 'f':
{
double value = va_arg(va,double);
printf("%f",value);
}
break;
case 's':
{
char *value = va_arg(va,char*);
printf("%s",value);
}
break;
default:
printf("%%");
}
translate(va,cmd+2);
}
}