转载自:http://blog.csdn.net/ID314846818/article/details/51074283

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宏,所以参数不能声明为寄存器变量,或作为函数或数组类型

va_list使用方法相关推荐

  1. C语言的va_list使用方法

    一.定义 在C++中又函数重载功能,C语言中也是又类似功能的,如经常见到的  int fun(char *format, ... ),该函数的参数个数是未定的,以此实现了类似重载的功能,我们用的最多的 ...

  2. Android 系统(241)---IPv4 or IPv6 优先

    IPv4 or IPv6 Prefer 如果apn的protocol设置为IPv4/IPv6的话,那么使用DNS解析某地址时,可能会同时返回IPv4和IPv6的地址. 但是某些服务端并未作好对IPv6 ...

  3. NDK - JNI官方中文资料

    NDK-JNI官方中文资料 声明 该篇文章完全引用自<JNI完全手册>完整版,用来方便查询查阅.感谢原文档作者. 文档所依赖的版本是比较低的,但是恰恰是低版本才能更容易上手学习.文档也有些 ...

  4. fmdb和mysql的区别_FMDB 使用进阶

    数据库.jpg 目录: 序 类文件解读 更多你不知道的API 关于事物的使用 数据库升级 序 只要是撸过一遍FMDB的人,基本都知道怎么用,增.删.改.查,偶尔涉及多表操作,多条件查询,搜搜sql语句 ...

  5. 在 Oracle Enterprise Linux 和 iSCSI 上构建您自己的 Oracle RAC 11g 集群

    作者:Jeffrey Hunter 了解如何以低于 2,700 美元的费用在 Oracle Enterprise Linux 上安装并配置 Oracle RAC 11g 第 2 版开发集群. 本指南中 ...

  6. Java面试题大全2021版

    一.Java 基础 JDK 和 JRE 有什么区别? JDK:Java Development Kit 的简称,java 开发工具包,提供了 java 的开发环境和运行环境. JRE:Java Run ...

  7. 理解可变参数va_list、va_start、va_arg、va_end原理及使用方法

     参考: http://www.360doc.com/content/12/0309/10/4025635_192940551.shtml http://www.cnblogs.com/Annie ...

  8. c语言 变参函数的使用方法,c语言变参函数的vsprintf与va_list的用法

    在调cgi的时候原本想写一个简单的log,但是入参始终不对,昨晚很丧气,今早起来再查看,发现了bug 之前是这么写的,arg得到的值却总是不对,然后才发现有vsprintf函数专门用来函数变参的: i ...

  9. va_list、va_start和va_end使用

    我们知道va_start,va_arg,va_end是在stdarg.h中被定义成宏的,由于1.硬件平台的不同 2.编译器的不同,所以定义的宏也有所不同. 在ANSI C中,这些宏的定义位于stdar ...

  10. JNI中C调用Java方法

     我们需要在JNI的C代码调用Java代码.实现原理:使用JNI提供的反射借口来反射得到Java方法,进行调用. JNI关键方法讲解. 1. 在同一个类中,调用其他方法 JNIEXPORT voi ...

最新文章

  1. YOLO算法史上最全综述:从YOLOv1到YOLOv5
  2. MongoDB 是如何鼓励和激励开发者社区的
  3. 我的第一个用Hibernate框架写的小例子
  4. tomcat配置多个web网站的配置详解
  5. c 字符串数组_在C++中将字符串转换为char数组
  6. java .insert_Java StringBuffer.insert 插入字符
  7. 【操作系统/OS笔记04】内存分层体系、地址生成、连续内存分配概论
  8. 玩家国度ROG 幻14 拆机 升级 换固态 换配件 教程
  9. python 列表相关应用大全
  10. 遥感原理与应用:绪论基础知识
  11. 风尚云网学习-前端页面敏感数据脱敏星号展示
  12. PHP解析大型Excel表格的库:box/spout
  13. (近5w字)面向小白のVue全家桶开发电商管理系统项目总结文档
  14. Wap与Net之争!!
  15. 【英语】-吞音与连读
  16. 如何写好一份产品需求文档
  17. 【高级数理统计R语言学习】5 协方差分析
  18. 单表无条件和有条件查询的SQL语句
  19. 网易我的世界手游服务器怎么发全体信息,网易我的世界手机怎么私聊 | 手游网游页游攻略大全...
  20. 你的电脑里还在装着360杀毒软件吗?最好用的,免费的都在这里,给你的电脑换个好的杀软~!...

热门文章

  1. LaTeX 参考文献的处理
  2. 振荡电路设计原理与设计
  3. [编程实例]360漏洞修复(绿色版)制作器 v1.0
  4. 英语3500词(八)treat kids as adults主题(2022.1.20)
  5. 小白刷LeeCode(算法篇)5
  6. 多臂老虎机(Multi-armed Bandit)MAB学习笔记
  7. 数学分析习题解答(四:第一部分)
  8. 计算机资源管理器出问题怎么办,电脑资源管理器运行异常导致任务栏出现问题...
  9. ChucK初步(2)
  10. 还原html默认打开方式,Win7旗舰版64位系统下如何还原文件默认打开方式