va_start、va_end、va_list的使用

 

 

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
4

 

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!", "");

}

 

int demo(char msg, ...)

{

     va_list argp;

     int argno = 0;

     char para;

    

     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);

 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;

}

摘至:http://www.cnblogs.com/rainduck/archive/2010/11/10/1873417.html

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值