打印本文 打印本文  关闭窗口 关闭窗口  
va_start()va_end()函数应用
作者:佚名  文章来源:不详  点击数  更新时间:2008/4/18 14:38:24  文章录入:杜斌  责任编辑:杜斌

1:当无法列出传递函数的所有实参的类型和数目时,可用省略号指定参数表 
void foo(...); 
void foo(parm_list,...); 

2:函数参数的传递原理 
函数参数是以数据结构:栈的形式存取,从右至左入栈.eg: 
#include <iostream>   
void fun(int a, ...)  
{  
int *temp = &a;  
temp++;  
for (int i = 0; i < a; ++i)  
{  
cout << *temp << endl;  
temp++;  
}  
}  
int main()  
{  
int a = 1;  
int b = 2;  
int c = 3;  
int d = 4;  
fun(4, a, b, c, d);  
system("pause");  
return 0;  
}  
Output::  
1  
2  
3  


3:获取省略号指定的参数 
在函数体中声明一个va_list,然后用va_start函数来获取参数列表中的参数,使用完毕后调用va_end()结束。像这段代码:  
void TestFun(char* pszDest, int DestLen, const char* pszFormat, ...)  
{  
va_list args;  
va_start(args, pszFormat);  
_vsnprintf(pszDest, DestLen, pszFormat, args);  
va_end(args);  


4.va_start使argp指向第一个可选参数。va_arg返回参数列表中的当前参数并使argp指向参数列表中的下一个参数。va_end把argp指针清为NULL。函数体内可以多次遍历这些参数,但是都必须以va_start开始,并以va_end结尾。 
  1).演示如何使用参数个数可变的函数,采用ANSI标准形式  
  #include 〈stdio.h〉  
  #include 〈string.h〉  
  #include 〈stdarg.h〉  
  /*函数原型声明,至少需要一个确定的参数,注意括号内的省略号*/  
  int demo( char, ... );  
  void main( void )  
  {  
     demo("DEMO", "This", "is", "a", "demo!", "");  
  }  
  /*ANSI标准形式的声明方式,括号内的省略号表示可选参数*/  
  int demo( char msg, ... )  
  {  
       /*定义保存函数参数的结构*/ 
     va_list argp;  
     int argno = 0;   
     char para;  
     /*argp指向传入的第一个可选参数,msg是最后一个确定的参数*/  
     va_start( argp, msg );  
     while (1)  
       {  
      para = va_arg( argp, char);  
        if ( strcmp( para, "") == 0 )  
       break;  
         printf("Parameter #%d is: %s\n", argno, para);  
         argno++;  
    }  
    va_end( argp );  
    /*将argp置为NULL*/ 
   return 0;  
  }  

2)//示例代码1:可变参数函数的使用 
#include "stdio.h" 
#include "stdarg.h" 
void simple_va_fun(int start, ...)  
{  
    va_list arg_ptr;  
   int nArgValue =start; 
    int nArgCout=0;     //可变参数的数目 
    va_start(arg_ptr,start); //以固定参数的地址为起点确定变参的内存起始地址。 
    do 
    { 
        ++nArgCout; 
        printf("the %d th arg: %d\n",nArgCout,nArgValue);     //输出各参数的值 
        nArgValue = va_arg(arg_ptr,int);                      //得到下一个可变参数的值 
    } while(nArgValue != -1);                 
    return;  

int main(int argc, char* argv[]) 

    simple_va_fun(100,-1);  
    simple_va_fun(100,200,-1);  
    return 0; 


3)//示例代码2:扩展——自己实现简单的可变参数的函数。 
下面是一个简单的printf函数的实现,参考了<The C Programming Language>中的例子 
#include "stdio.h" 
#include "stdlib.h" 
void myprintf(char* fmt, ...)        //一个简单的类似于printf的实现,//参数必须都是int 类型 
{  
    char* pArg=NULL;               //等价于原来的va_list  
    char c; 
     
    pArg = (char*) &fmt;          //注意不要写成p = fmt !!因为这里要对//参数取址,而不是取值
   pArg += sizeof(fmt);         //等价于原来的va_start           
  
    do 
    { 
        c =*fmt; 
        if (c != ’%’) 
        { 
            putchar(c);            //照原样输出字符 
        } 
        else 
        { 
           //按格式字符输出数据 
           switch(*++fmt)  
           { 
            case’d’: 
                printf("%d",*((int*)pArg));            
                break; 
            case’x’: 
                printf("%#x",*((int*)pArg)); 
                break; 
            default: 
                break; 
            }  
            pArg += sizeof(int);               //等价于原来的va_arg 
        } 
        ++fmt; 
    }while (*fmt != ’\0’);  
    pArg = NULL;                               //等价于va_end 
    return;  

int main(int argc, char* argv[]) 

    int i = 1234; 
    int j = 5678; 
     
    myprintf("the first test:i=%d\n",i,j);  
    myprintf("the secend test:i=%d; %x;j=%d;\n",i,0xabcd,j);  
    system("pause"); 
    return 0; 
}
打印本文 打印本文  关闭窗口 关闭窗口