va_start() va_end()函数应用

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

void foo(...); 
void foo(parm_list,...); 
 
2:函数参数的传递原理 
函数参数是以数据结构:栈的形式存取,从右至左入栈.eg: 
#include    
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&NBSP;C&NBSP;PROGRAMMING&NBSP;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; 
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值