感性认识
Typedef char *va_list;/*这个在<stdatg.h>中有定义*/ #define va_start(ap,p) (ap=(char*)(&(p)+1)) #define va_arg(ap,type) ((type*)(ap+=sizeof(type)))[-1] #defien va_end(ap) /*下面为测试函数*/ #include<stdio.h> #include<stdlib.h> #include<stdarg.h> void fun(char *s, ... ) /* ...为声明不定个数参数*/ { va_list ap; int t; /*与main()中的a,b,c 相同的类型声明*/ va_start(ap,s); printf("%s",s); while((t=va_arg(ap,int))) printf("%d",t); va_end(ap); } main() { int a=1,b=2,c=3; fun('test:",a,b,c,NULL);/*以NULL作结束*/ printf(" "); }
解释内部宏定义
1、#define va_start(ap,p) (ap=(char*)(&(p)+1))
参数ap: 获取fun函数形参 ... 中第一个元素地址;
2、#define va_arg(ap,type) ((type*)(ap+=sizeof(type)))[-1]
参数ap: 移动到后一个参数元素地址;
1)、ap 是字符指针,所有ap+1意思是向下移动一个地址[因为一个地址存放8位(一个字符)],
2)、ap += sizeof(type):意思是更具类型移动相应的位置;[如果type是int型那么ap向后移4个地址]
3)、(type *)(指针地址)[-1]:整体含义就是回到ap上一个地址位置;
(type *)(指针地址):指向ap下一个指针地址强转为(type *)型;
(指针地址)[-1]:根据指针地址类型向后前移动一个位置;[如果type是int,就向前移4个地址]
[注意:
1)、一个地址存放8位;
2)、指针移动的位置是依据指针类型移动的;
如果 char * p,移动则是1个地址;如果 char ** p,移动则是4个地址(char ** 指针32位存储); 如果 int * p,移动则是也是4个地址(int * 也是一个指针地址)]
#defien va_end(ap)
表示结束。