根据定义(va_list)&v得到起始参数的地址, 再加上_INTSIZEOF(v) ,就是其实参数下一个参数的地址,即第一个可变参数地址.
j=va_arg(arg_ptr, int); 得到第一个参参数的值,并且arg_ptr指针上移一个_INTSIZEOF(int),即指向下一个可变参数的地址.
va_end(arg_ptr);置空arg_ptr,即arg_ptr=0;
总结:读取可变参数的过程其实就是堆栈中,使用指针,遍历堆栈段中的参数列表,从低地址到高地址一个一个地把参数内容读出来的过程.
void arg_test(int i, ...)
{
int j=0;
va_list arg_ptr;
va_start(arg_ptr, i);
printf("&i = %p/n", &i);//打印参数i在堆栈中的地址
printf("arg_ptr = %p/n", arg_ptr);
//打印va_start之后arg_ptr地址,
//应该比参数i的地址高sizeof(int)个字节
//这时arg_ptr指向下一个参数的地址
j=*((int *)arg_ptr);
printf("%d %d/n", i, j);
j=va_arg(arg_ptr, int);
printf("arg_ptr = %p/n", arg_ptr);
//打印va_arg后arg_ptr的地址
//应该比调用va_arg前高sizeof(int)个字节
//这时arg_ptr指向下一个参数的地址
va_end(arg_ptr);
printf("%d %d/n", i, j);
}
void arg_cnt(int cnt, ...)
{
int value=0;
int i=0;
int arg_cnt=cnt;
va_list arg_ptr;
va_start(arg_ptr, cnt);
for(i = 0; i < cnt; i++)
{
value = va_arg(arg_ptr,int);
printf("value%d=%d/n", i+1, value);
}
}
void arg_type(int cnt, ...)
{
int arg_type = 0;
int int_value=0;
int i=0;
int arg_cnt=cnt;
char *str_value = NULL;
va_list arg_ptr;
va_start(arg_ptr, cnt);
for(i = 0; i < cnt; i++)
{
arg_type = va_arg(arg_ptr,int);
switch(arg_type)
{
case INT_TYPE:
int_value = va_arg(arg_ptr,int);
printf("value%d=%d/n", i+1, int_value);
break;
case STR_TYPE:
str_value = va_arg(arg_ptr,char*);
printf("value%d=%d/n", i+1, str_value);
break;
default:
break;
}
}
}
以上是我个人的见解,不对的地方希望大家指正,发表看法,我不胜感谢!!!
#include <stdio.h> #include <stdarg.h> const int INT_TYPE = 100000; const int STR_TYPE = 100001; const int CHAR_TYPE = 100002; const int LONG_TYPE = 100003; const int FLOAT_TYPE = 100004; const int DOUBLE_TYPE = 100005; void arg_type(int cnt, ...); void arg_cnt(int cnt, ...); void arg_test(int i, ...); int main(int argc,char *argv[]) { int int_size = _INTSIZEOF(int); printf("int_size=%d/n", int_size); arg_test(0, 4); arg_cnt(4,1,2,3,4); arg_type(2, INT_TYPE, 222, STR_TYPE, "ok,hello world!"); return 0; } void arg_test(int i, ...) { int j=0; va_list arg_ptr; va_start(arg_ptr, i); printf("&i = %p/n", &i);//打印参数i在堆栈中的地址 printf("arg_ptr = %p/n", arg_ptr); //打印va_start之后arg_ptr地址, //应该比参数i的地址高sizeof(int)个字节 //这时arg_ptr指向下一个参数的地址 j=*((int *)arg_ptr); printf("%d %d/n", i, j); j=va_arg(arg_ptr, int); printf("arg_ptr = %p/n", arg_ptr); //打印va_arg后arg_ptr的地址 //应该比调用va_arg前高sizeof(int)个字节 //这时arg_ptr指向下一个参数的地址 va_end(arg_ptr); printf("%d %d/n", i, j); } void arg_cnt(int cnt, ...) { int value=0; int i=0; int arg_cnt=cnt; va_list arg_ptr; va_start(arg_ptr, cnt); for(i = 0; i < cnt; i++) { value = va_arg(arg_ptr,int); printf("value%d=%d/n", i+1, value); } } void arg_type(int cnt, ...) { int arg_type = 0; int int_value=0; int i=0; int arg_cnt=cnt; char *str_value = NULL; va_list arg_ptr; va_start(arg_ptr, cnt); for(i = 0; i < cnt; i++) { arg_type = va_arg(arg_ptr,int); switch(arg_type) { case INT_TYPE: int_value = va_arg(arg_ptr,int); printf("value%d=%d/n", i+1, int_value); break; case STR_TYPE: str_value = va_arg(arg_ptr,char*); printf("value%d=%s/n", i+1, str_value); break; default: break; } } }