va_list 是C语言中解决变参问题的一组宏。

1.API介绍:
头文件:

[cpp]  view plain copy print ?
  1. #include <stdarg.h>

下面是实现变参函数的一组宏(macro):

[cpp]  view plain copy print ?
  1. void va_start(va_list ap, last);
  2. type va_arg(va_list ap, type);
  3. void va_end(va_list ap);
  4. void va_copy(va_list dest, va_list src);

2.具体介绍:

[cpp]  view plain copy print ?
  1. void va_start(va_list ap, last);

va_start用于初始化变参结构ap,其中va_list是与变参列表相关的结构,里面保存着变参列表的信息包括变参列表的指针。
last是变参函数的可变参数列表的前一个参数,用于确定可变参数的内存地址;

[cpp]  view plain copy print ?
  1. type va_arg(va_list ap, type);

va_arg取出当前的参数用于返回,并且把变参列表指针指向下一个参数。其中ap是经过va_start初始化的变参结构,type是变参的类型。

[cpp]  view plain copy print ?
  1. void va_end(va_list ap);

va_end用于结束对可变参数的获取,释放相应的资源,将ap清零。va_end和va_start成对使用。

[cpp]  view plain copy print ?
  1. void va_copy(va_list dest, va_list src);

用于复制变参结构。由于具体实现不同,变参结构本身或是结构里面的参数时指针,而简单的赋值操作会造成浅拷贝,
当其中一个结构的指针被释放空间的时候(va_end释放空间),另一个结构的指针会成为野指针,可能就会出问题,所以对于va_list型的变量来说,禁止直接赋值(=),要用va_copy进行拷贝。

3.用法:

a.首先在函数里定义一具va_list型的变量:
b.然后用va_start宏初始化变量刚定义的va_list变量,这个宏的第二个参数是第一个可变参数的前一个参数,是一个固定的参数。
c.然后用va_arg返回可变的参数,va_arg的第二个参数是你要返回的参数的类型。如果函数有多个可变参数的,依次调用va_arg获取各个参数。
d.最后用va_end宏结束可变参数的获取。

4.例子:

[html]  view plain copy print ?
  1. #include <stdio.h>
  2. #include <stdarg.h>
  3. void foo(char *fmt, ...)
  4. {
  5. va_list ap;
  6. int d;
  7. char c, *s;
  8. va_start(ap, fmt);
  9. while (*fmt)
  10. switch (*fmt++)
  11. {
  12. case 's':              /* string */
  13. s = va_arg(ap, char *);
  14. printf("string %s\n", s);
  15. break;
  16. case 'd':              /* int */
  17. d = va_arg(ap, int);
  18. printf("int %d\n", d);
  19. break;
  20. case 'c':              /* char */
  21. /* need a cast here since va_arg only
  22. takes fully promoted types */
  23. c = (char) va_arg(ap, int);
  24. printf("char %c\n", c);
  25. break;
  26. }
  27. va_end(ap);
  28. }

5.使用VA_LIST应该注意的问题:

a.可变参数的类型和个数完全由程序代码控制,它并不能智能地识别不同参数的个数和类型;
b.由于各个平台对va_list的实现可能会用不同,所以严格的通过va_start、va_arg、va_end、va_copy来使用va_list很有必要,不建议直接对其进行指针操作;
c.因为编译器对可变参数的函数的原型检查不够严格,对编程查错不利。不利于我们写出高质量的代码;
d.va_start,va_arg,va_end是在C89标准中定义的。va_copy是在C99标准中定义的。

【valist】c语言可变参数宏相关推荐

  1. c语言宏定义可变参数,C语言可变参数宏定义方法

    http://blog.csdn.net/skyflying2012/article/details/38436711 2014 在GNU C中,宏可以接受可变数目的参数,就象函数一样,例如: 1 2 ...

  2. #{}不自动改参数类型_【Just For Fun】C - 可变参数函数、可变参数宏 __VA_ARGS__、额外的逗号

    [Just For Fun] 本系列纯粹娱乐.研究用.一些旁门左道的东西. 事实上可能完全没用. (๑•̀ω•́๑) 對於可变参数函数.可变参数宏 __VA_ARGS__ , 我曾經有在另一些地方寫過 ...

  3. c语言 可变参数的宏,可变参数的宏__ VA_ARGS__的用法

    回顾 在[ANSIC几种特殊的标准定义]中我们讲述了比较常用的几项: __FILE__:正在编译文件的路径及文件名 __LINE__:正在编译文件的行号 __DATE__:编译时刻的日期字符串 如&q ...

  4. 【嵌入式】C语言高级编程-可变参数宏(12)

    00. 目录 文章目录 00. 目录 01. 可变参数宏概述 02. ##符号 03. 可变参宏另外一种写法 04. 内核中的可变参数宏 05. 附录 01. 可变参数宏概述 #include < ...

  5. c语言宏不能传递参数,关于c ++:可变参数宏:不能通过’…’传递非平凡复制类型的对象...

    我正在尝试为日志记录机制编写宏. 我编写了一个可变参数宏,但它不适用于std::string. 该代码如下所示: #include #include #define LOG_NOTE(m, ...) ...

  6. C语言可变参数函数_初探

    一.什么是可变参数函数 C语言允许定义参数数量可变的函数,这称为可变参数函数(variadic function).这种函数需要固定数量的强制参数,后面是数量可变的可选参数. 其中,强制参数必须至少一 ...

  7. C语言可变参数函数(printf/scanf)

    C 语言允许定义参数数量可变的函数,这称为可变参数函数(variadic function).这种函数需要固定数量的强制参数(mandatory argument),后面是数量可变的可选参数(opti ...

  8. c语言怎样获得函数内参数的值_C语言可变参数函数的实现原理

    在本人的<C语言可变参数函数的实现方法>一文中,介绍了如何建立自己的可变参数函数. 下面继续介绍可变参数函数的实现原理. 在汇编语言程序设计中,详细介绍了子程序的实现思想: (1)子程序只 ...

  9. next用法C语言,C语言可变参数的使用

    先来个简单的例子:#include #include void test0(int num,...) { va_list ap; va_start(ap, num); while(num--) { p ...

最新文章

  1. 新产品发布与A轮2000万美元 双喜临门后GrowingIO还要做什么
  2. 零基础入门学习Python,我与python的第一次亲密接触后的感受!
  3. Linux下C语言使用、编译与调试
  4. python安装第三方库太慢_Python 安装第三方库 pip install 安装慢安装不上的解决办法...
  5. redhat安装wine教程_Ubuntu怎么下载应用并安装应用
  6. php怎么实现商品评论功能,php购物车功能如何实现
  7. 值得借鉴的30条好习惯
  8. NLP《词汇表示方法(七)BERT》
  9. 源码之前,了无秘密(一)——iterator adapter
  10. httphandler防图片盗链
  11. java jpg转换成pdf格式_Java pdf和jpg互转案例
  12. Google Chrome Frame 谷歌浏览器框架
  13. 仿IBM首页焦点图,缩略图大图,带文字
  14. 中国地理省份行政区划,代表文化收集整理
  15. 为串的模式匹配。模式匹
  16. 字符串分隔StringUtils.delimitedListToStringArray
  17. 翻译:seq2seq model in Machine Learning
  18. github代码clone加速
  19. Symantec Backup Exec恢复数据库
  20. 横扫阿里、滴滴、美团后,3年经验的Java后端妹子整理出这份厚厚的面经!

热门文章

  1. 一个博士毕业之际写的一些发文章的心得
  2. Opencv学习笔记——图像基本操作
  3. UG数控编程3种螺旋刀路,可用于各种2d和3d加工过程
  4. 2017 ACM Arabella Collegiate Programming Contest A. Sherlock Bones GYM101350A
  5. 原地移除数组重复元素问题总结
  6. 志强系列的服务器能吃鸡吗,英特尔 xeon e5-2660能玩绝地求生吗
  7. 【代理工具使用必备知识汇总】:vpn、socks5、代理客户端使用
  8. python pyside简单布局_PySide2/PyQt5的4种基础布局管理
  9. 微信公众号(一键互粉)增粉平台的源码分享
  10. 在这个大数据时代,如何保护好自己的隐私?