#include <stdarg.h> #include <stdio.h> int AveInt(int,...); int Test(int,...); int main() { //printf("=%d ",AveInt(2,2,3)); //printf("=%d ",AveInt(9,2,4,6,8,2,3,4,5,6,7)); printf("(More)=%d ",Test(3,4,3,7,2,5,4,6,7)); return 0; } int AveInt(int v,...){ int ReturnValue=0; int i=v; va_list ap; va_start(ap,v); while(i>0) { int iii = va_arg(ap,int); printf("[%d]",iii); ReturnValue+= iii; i--; } va_end(ap); return ReturnValue/=v; } #define DEAL_MAIN va_start(ap,i); for(int j=0;j<i;j++){para[j] = va_arg(ap,int);} va_end(ap);
//一般给的参数都少于10 int Test(int i,...){ int para[i]; va_list ap; switch(i){ case 0: return AveInt(i); case 1: va_start(ap,i); for(int j=0;j<i;j++){para[j] = va_arg(ap,int);} va_end(ap); return AveInt(i,para[0]); case 2: DEAL_MAIN return AveInt(i,para[0],para[1]); case 3: DEAL_MAIN return AveInt(i,para[0],para[1],para[2]); case 4: DEAL_MAIN return AveInt(i,para[0],para[1],para[2],para[3]); case 5: DEAL_MAIN return AveInt(i,para[0],para[1],para[2],para[3],para[4]); case 6: DEAL_MAIN return AveInt(i,para[0],para[1],para[2],para[3], para[4],para[5]); case 7: DEAL_MAIN return AveInt(i,para[0],para[1],para[2],para[3], para[4],para[5],para[6]); case 8: DEAL_MAIN return AveInt(i,para[0],para[1],para[2],para[3],para[4], para[5],para[6],para[7]); case 9: DEAL_MAIN return AveInt(i,para[0],para[1],para[2],para[3],para[4], para[5],para[6],para[7],para[8]); case 10: DEAL_MAIN return AveInt(i,para[0],para[1],para[2],para[3],para[4], para[5],para[6],para[7],para[8],para[9]); } }
一、可变参数的使用
va_list ap ;
定义一个va_list变量ap
va_start(ap,v) ;
执行ap = (va_list)&v + _INTSIZEOF(v),ap指向参数v之后的那个参数的地址,即 ap指向第一个可变参数在堆栈的地址。
va_arg(ap,type) ;
( *(type *)((ap += _INTSIZEOF(type)) - _INTSIZEOF(type)) )取出当前ap指针所指的值,并使ap指向下一个参数。 ap+= sizeof(t类型),让ap指向下一个参数的地址。然后返回ap-sizeof(t类型)的t类型*指针,这正是第一个可变参数在堆栈里的地址。然后 用*取得这个地址的内容。
va_end(ap) ;清空va_list ap。
附部分VC6.0 x86下的宏源码
typedef char * va_list; // TC中定义为void* #define _INTSIZEOF(n) ((sizeof(n)+sizeof(int)-1)&~(sizeof(int) - 1) ) //为了满足需要内存对齐的系统 #define va_start(ap,v) ( ap = (va_list)&v + _INTSIZEOF(v) ) //ap指向第一个变参的位置,即将第一个变参的地址赋予ap #define va_arg(ap,t) ( *(t *)((ap += _INTSIZEOF(t)) - _INTSIZEOF(t)) ) /*获取变参的具体内容,t为变参的类型,如有多个参数,则通过移动ap的指针来获得变参的地址,从而获得内容*/ #define va_end(ap) ( ap = (va_list)0 ) //清空va_list,即结束变参的获取
二、函数与函数之间的可变参数传递
前提,一般可变参数不会操作10个参数,遵循这个要求,就可以解析可变参数,并且传入下个函数
亲测,按上边的函数可以
效果如图