VA_LIST 是在C语言中解决变参问题的一组宏,变参问题是指参数的个数不定,可以是传入一个参数也可以是多个;可变参数中的每个参数的类型可以不同,也可以相同;可变参数的每个参数并没有实际的名称与之相对应,用起来是很灵活。

va_list 用法示例

#include <stdarg.h> int AveInt(int,...);void main()
{printf("%d/t",AveInt(2,2,3));printf("%d/t",AveInt(4,2,4,6,8));return;
}int AveInt(int v,...)
{int ReturnValue=0;int i=v;va_list ap ;va_start(ap,v);while(i>0){ReturnValue+=va_arg(ap,int) ;i--;}va_end(ap); return ReturnValue/=v;
}

VA_LIST的用法:
(1)首先在函数里定义一具VA_LIST型的变量,这个变量是指向参数的指针;
(2)然后用VA_START宏初始化变量刚定义的VA_LIST变量;
(3)然后用VA_ARG返回可变的参数,VA_ARG的第二个参数是你要返回的参数的类型(如果函数有多个可变参数的,依次调用VA_ARG获取各个参数);
(4)最后用VA_END宏结束可变参数的获取。

上面是va_list的具体用法,下面讲解一下va_list各个语句含义(如上示例黑体部分)和va_list的实现。

     可变参数是由宏实现的,但是由于硬件平台的不同,编译器的不同,宏的定义也不相同,下面是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,即结束变参的获取

va_list ap ; 定义一个va_list变量ap
va_start(ap,v) ;执行ap = (va_list)&v + _INTSIZEOF(v),ap指向参数v之后的那个参数的地址,即 ap指向第一个可变参数在堆栈的地址。
va_arg(ap,t) , ( (t )((ap += _INTSIZEOF(t)) - _INTSIZEOF(t)) )取出当前ap指针所指的值,并使ap指向下一个参数。 ap+= sizeof(t类型),让ap指向下一个参数的地址。然后返回ap-sizeof(t类型)的t类型指针,这正是第一个可变参数在堆栈里的地址。然后 用取得这个地址的内容。
va_end(ap) ; 清空va_list ap。

使用VA_LIST应该注意的问题:
(1)因为va_start, va_arg, va_end等定义成宏,所以它显得很愚蠢,可变参数的类型和个数完全在该函数中由程序代码控制,它并不能智能地识别不同参数的个数和类型. 也就是说,你想实现智能识别可变参数的话是要通过在自己的程序里作判断来实现的.
(2)另外有一个问题,因为编译器对可变参数的函数的原型检查不够严格,对编程查错不利.不利于我们写出高质量的代码。
(3)由于参数的地址用于VA_START宏,所以参数不能声明为寄存器变量,或作为函数或数组类型。

参考文章:
http://blog.csdn.net/aihao1984/article/details/5953668

va_list 原理以及用法相关推荐

  1. mysql 实时聚合分析,mysql累积聚合原理与用法实例分析

    本文实例讲述了mysql累积聚合原理与用法.分享给大家供大家参考,具体如下: 累积聚合为聚合从序列内第一个元素到当前元素的数据,如为每个员工返回每月开始到现在累积的订单数量和平均订单数量 行号问题有两 ...

  2. python装饰器原理-Python装饰器原理与用法分析

    这篇文章主要介绍了Python装饰器原理与用法,结合实例形式分析了Python装饰器的概念.原理.使用方法及相关操作注意事项,需要的朋友可以参考下 本文实例讲述了Python装饰器原理与用法.分享给大 ...

  3. python的编程模式-Python设计模式之状态模式原理与用法详解

    本文实例讲述了Python设计模式之状态模式原理与用法.分享给大家供大家参考,具体如下: 状态模式(State Pattern):当一个对象的内在状态改变时允许改变其行为,这个对象看起来像是改变了其类 ...

  4. python装饰器原理-Python函数装饰器原理与用法详解

    本文实例讲述了Python函数装饰器原理与用法.分享给大家供大家参考,具体如下: 装饰器本质上是一个函数,该函数用来处理其他函数,它可以让其他函数在不需要修改代码的前提下增加额外的功能,装饰器的返回值 ...

  5. python装饰器原理-python装饰器原理与用法深入详解

    本文实例讲述了python装饰器原理与用法.分享给大家供大家参考,具体如下: 你会Python嘛? 我会! 那你给我讲下Python装饰器吧! Python装饰器啊?我没用过哎 以上是我一个哥们面试时 ...

  6. python定义私有变量的方法_Python面向对象程序设计之私有变量,私有方法原理与用法分析...

    本文实例讲述了Python面向对象程序设计之私有变量,私有方法原理与用法.分享给大家供大家参考,具体如下: 私有变量,私有方法:python的私有化是为了规划私有属性,避免非相关的访问[假如!我有老婆 ...

  7. mysql 实时聚合分析_mysql滑动聚合/年初至今聚合原理与用法实例分析

    本文实例讲述了mysql滑动聚合/年初至今聚合原理与用法.分享给大家供大家参考,具体如下: 滑动聚合是按顺序对滑动窗口范围内的数据进行聚合的操作.下累积聚合不同,滑动聚合并不是统计开始计算的位置到当前 ...

  8. java 字节缓冲_Java字节缓冲流原理与用法详解

    本文实例讲述了Java字节缓冲流原理与用法.分享给大家供大家参考,具体如下: 一 介绍 BufferInputStresm和BufferOutputStream 这两个流类为IO提供了带缓冲区的操作, ...

  9. mysql的存储过程原理_mysql存储过程原理与用法详解

    本文实例讲述了Mysql存储过程原理与用法.分享给大家供大家参考,具体如下: 本文内容: 什么是存储过程 存储过程的创建 存储过程的使用 查看存储过程 修改存储过程 删除存储过程 首发日期:2018- ...

  10. python异常处理_汇总三大python异常处理、自定义异常、断言原理与用法分析

    本文实例讲述了python异常处理.自定义异常.断言原理与用法.分享给大家供大家参考,具体如下: 什么是异常: 当程序遭遇某些非正常问题的时候就会抛出异常:比如int()只能处理能转化成int的对象, ...

最新文章

  1. 作为一名准程序员,谈一下现实和未来
  2. linux进程间通讯-共享内存
  3. php图片编辑失真,PHP上传真彩图片缩略图质量失真解决方法
  4. Javascript实现动态菜单添加
  5. html代码type,HTML中type是什么意思
  6. 云原生开发环境初探 | CSDN 博文精选
  7. 再议动态二维数组,通过一句表达式完成矩阵的转置
  8. installshield中用release wizard打包.net framework 1.1中文版
  9. Ubuntu下连接共享打印机的方法
  10. unity2d自动生成敌人_在Unity 2D中产生敌人
  11. vue-pdf 报错 RenderingCancelledException:Rendering cancelled, page 1
  12. 使用ShareSDK实现QQ登录和分享操作
  13. 中国卸扣市场趋势报告、技术动态创新及市场预测
  14. 顶级域名、一级域名、二级域名、子域名如何区分
  15. C# serialport串口接收数据异常,出现很多3F的解决方法
  16. 2022年前端面试题
  17. 某Y易盾滑块acToken、data逆向分析
  18. 多任务多目标 CTR 预估技术
  19. C#MVC Razor的Ajax.BeginForm里面的OnSuccess未执行(未成功跳转)
  20. int i2c_probe()

热门文章

  1. web安全实验:Attack1-6
  2. 你需要知道的WAMP5
  3. Git Github操作简易教程
  4. linux怎么生成arm文件,AMR 文件扩展名: 它是什么以及如何打开它?
  5. illustrator插件-拼版功能开发-裁切标记-js脚本开发-ai插件
  6. 基于SSM的设备租赁管理系统
  7. 开源项目—swift开发记事本APP
  8. 现在的媒体时兴“毁人不倦”?
  9. 用js处理图片加载错误时加载默认图片的方法
  10. 让你快速逃离万能五笔的广告