C/C++多参数处理

#include <stdarg.h> 
#include <stdio.h>

int AveInt(int,...);
int Test(int,...);

 int main()
 {

       //printf("=%d\t",AveInt(2,2,3));

       //printf("=%d\t",AveInt(9,2,4,6,8,2,3,4,5,6,7));
       
       printf("(More)=%d\t",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个参数,遵循这个要求,就可以解析可变参数,并且传入下个函数

 

亲测,按上边的函数可以

效果如图

posted @ 2015-07-30 09:25  冰雪一舟  阅读(723)  评论(0编辑  收藏  举报