首先声明下面这个va_list的实现,只适用于32位的机器,像单片机这样int 是2Byte的不适合,但是原理是一样的。
-
typedef char * va_list;
-
#define _INTSIZEOF(n) ((sizeof(n)+sizeof(int)-1)&~(sizeof(int) - 1) )
-
#define va_start(ap,v) ( ap = (va_list)&v + _INTSIZEOF(v) )
-
#define va_arg(ap,t) ( *(t *)((ap += _INTSIZEOF(t)) - _INTSIZEOF(t)) )
-
#define va_end(ap) ( ap = (va_list)0 )
-
-
void test_vparameter(int i,...)
-
{
-
int mm;
-
va_list argv;
-
va_start(argv,i);
-
while(i--)
-
{
-
mm=va_arg(argv,int);
-
putc(mm);
-
}
-
va_end(argv);
-
}
1. va_list
在调用va_start之前参数都己压入栈中,因为其它的都是可变参数,只有fmt是确定的,fmt是最后压入栈中的,并且每个参数在栈中占用的空间是一样的,所以可以由第一个参数fmt依次推算出其它参数的地址。
2. va_start
a. (va_list)&t 取第一个参数fmt的地址
b. (va_list)&t+_INT_SIZEOF(t) 第一个参数的地址加上参数的长度,此时ap指向了第二个参数即ap指向了第一个可变的参数。
3. va_arg
a. ap+=__INT_SIZEOF(t)
ap移动指向第二个可变参数
b. (ap+=__INT_SIZEOF(t))-__INT_SIZEOF(t)
用指针运算,确定第一个可变参数的地址
c. (t*)((ap+=__INT_SIZEOF(t))-__INT_SIZEOF(t))
进行强制类型转化
d. (*(t*)((ap+=__INT_SIZEOF(t))-__INT_SIZEOF(t)))
取出第一个可变参数地址中的值
阅读(3284) | 评论(0) | 转发(1) |