va_start() va_end()函数应用

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

2:函数参数的传递原理
函数参数是以数据结构:栈的形式存取,从右至左入栈.eg:
 1  #include  < iostream >   
 2  void  fun( int  a, 
 3 
 4  int   * temp  =   & a; 
 5  temp ++
 6  for  ( int  i  =   0 ; i  <  a;  ++ i) 
 7 
 8  cout  <<   * temp  <<  endl; 
 9  temp ++
10 
11 
12 
13  int  main() 
14 
15  int  a  =   1
16  int  b  =   2
17  int  c  =   3
18  int  d  =   4
19  fun( 4 , a, b, c, d); 
20  system( " pause " ); 
21  return   0
22 

Output:: 



4

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

4.va_start使argp指向第一个可选参数。va_arg返回参数列表中的当前参数并使argp指向参数列表中的下一个参数。va_end把argp指针清为NULL。函数体内可以多次遍历这些参数,但是都必须以va_start开始,并以va_end结尾。

1).演示如何使用参数个数可变的函数,采用ANSI标准形式 
 1  #include 〈stdio.h〉 
 2    #include 〈 string .h〉 
 3    #include 〈stdarg.h〉 
 4     /* 函数原型声明,至少需要一个确定的参数,注意括号内的省略号 */  
 5     int  demo(  char  ); 
 6     void  main(  void  ) 
 7    { 
 8     demo( " DEMO " " This " " is " " a " " demo! " "" ); 
 9    } 
10     /* ANSI标准形式的声明方式,括号内的省略号表示可选参数 */  
11     int  demo(  char  �msg,  ) 
12    { 
13     /* 定义保存函数参数的结构 */
14     va_list argp; 
15      int  argno  =   0 ;  
16      char  para; 
17 
18      /* argp指向传入的第一个可选参数,msg是最后一个确定的参数 */  
19     va_start( argp, msg ); 
20      while  ( 1
21    { 
22     para  =  va_arg( argp,  char ); 
23      if  ( strcmp( para,  "" ==   0  ) 
24     break
25     printf( " Parameter #%d is: %s\n " , argno, para); 
26     argno ++
27     } 
28     va_end( argp ); 
29      /* 将argp置为NULL */
30      return   0
31    } 

2)//示例代码1:可变参数函数的使用
 1  #include  " stdio.h "
 2  #include  " stdarg.h "
 3  void  simple_va_fun( int  start, 
 4 
 5    va_list arg_ptr; 
 6     int  nArgValue  = start;
 7     int  nArgCout = 0 // 可变参数的数目
 8    va_start(arg_ptr,start);  // 以固定参数的地址为起点确定变参的内存起始地址。
 9     do
10    {
11     ++ nArgCout;
12    printf( " the %d th arg: %d\n " ,nArgCout,nArgValue);  // 输出各参数的值
13    nArgValue  =  va_arg(arg_ptr, int );  // 得到下一个可变参数的值
14    }  while (nArgValue  !=   - 1 );  
15     return
16  }
17  int  main( int  argc,  char *  argv[])
18  {
19    simple_va_fun( 100 , - 1 ); 
20    simple_va_fun( 100 , 200 , - 1 ); 
21     return   0 ;
22  }


3)//示例代码2:扩展——自己实现简单的可变参数的函数。
下面是一个简单的printf函数的实现,参考了<The C Programming Language>中的例子
 1  #include  " stdio.h "
 2  #include  " stdlib.h "
 3  void  myprintf( char *  fmt,  // 一个简单的类似于printf的实现, // 参数必须都是int 类型
 4 
 5     char *  pArg = NULL;  // 等价于原来的va_list 
 6     char  c;
 7     
 8    pArg  =  ( char * & fmt;  // 注意不要写成p = fmt !!因为这里要对 // 参数取址,而不是取值
 9    pArg  +=   sizeof (fmt);  // 等价于原来的va_start  
10   
11     do
12    {
13    c  =* fmt;
14     if  (c  !=   ' % ' )
15    {
16    putchar(c);  // 照原样输出字符
17    }
18     else
19    {
20     // 按格式字符输出数据
21     switch ( *++ fmt) 
22    {
23     case ' d ' :
24    printf( " %d " , * (( int * )pArg));  
25     break ;
26     case ' x ' :
27    printf( " %#x " , * (( int * )pArg));
28     break ;
29     default :
30     break ;
31    } 
32    pArg  +=   sizeof ( int );  // 等价于原来的va_arg
33    }
34     ++ fmt;
35    } while  ( * fmt  !=   ' \0 ' ); 
36    pArg  =  NULL;  // 等价于va_end
37     return
38  }
39  int  main( int  argc,  char *  argv[])
40  {
41     int  i  =   1234 ;
42     int  j  =   5678 ;
43     
44    myprintf( " the first test:i=%d\n " ,i,j); 
45    myprintf( " the secend test:i=%d; %x;j=%d;\n " ,i, 0xabcd ,j); 
46    system( " pause " );
47     return   0 ;
48  }


转载于:https://www.cnblogs.com/phonefans/archive/2008/12/24/1361635.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值