VA_LIST 是在C语言中解决变参问题的一组宏
来源:互联网 发布:手机自动呼叫软件 编辑:程序博客网 时间:2024/06/05 12:43
VA_LIST 是在C语言中解决变参问题的一组宏
VA_LIST的用法:
(1)首先在函数里定义一具VA_LIST型的变量,这个变量是指向参数的指针
(2)然后用VA_START宏初始化变量刚定义的VA_LIST变量,这个宏的第二个参数是第一个可变参数的前一个参数,是一个固定的参数。
(3)然后用VA_ARG返回可变的参数,VA_ARG的第二个参数是你要返回的参数的类型。
(4)最后用VA_END宏结束可变参数的获取。然后你就可以在函数里使用第二个参数了。如果函数有多个可变参数的,依次调用VA_ARG获取各个参数。
(1)首先在函数里定义一具VA_LIST型的变量,这个变量是指向参数的指针
(2)然后用VA_START宏初始化变量刚定义的VA_LIST变量,这个宏的第二个参数是第一个可变参数的前一个参数,是一个固定的参数。
(3)然后用VA_ARG返回可变的参数,VA_ARG的第二个参数是你要返回的参数的类型。
(4)最后用VA_END宏结束可变参数的获取。然后你就可以在函数里使用第二个参数了。如果函数有多个可变参数的,依次调用VA_ARG获取各个参数。
VA_LIST在编译器中的处理:
(1)在运行VA_START(ap,v)以后,ap指向第一个可变参数在堆栈的地址。
(2)VA_ARG()取得类型t的可变参数值,在这步操作中首先apt = sizeof(t类型),让ap指向下一个参数的地址。然后返回ap-sizeof(t类型)的t类型*指针,这正是第一个可变参数在堆栈里的地址。然后用*取得这个地址的内容。
(3)VA_END(),X86平台定义为ap = ((char*)0),使ap不再指向堆栈,而是跟NULL一样,有些直接定义为((void*)0),这样编译器不会为VA_END产生代码,例如gcc在Linux的X86平台就是这样定义的。
(2)VA_ARG()取得类型t的可变参数值,在这步操作中首先apt = sizeof(t类型),让ap指向下一个参数的地址。然后返回ap-sizeof(t类型)的t类型*指针,这正是第一个可变参数在堆栈里的地址。然后用*取得这个地址的内容。
(3)VA_END(),X86平台定义为ap = ((char*)0),使ap不再指向堆栈,而是跟NULL一样,有些直接定义为((void*)0),这样编译器不会为VA_END产生代码,例如gcc在Linux的X86平台就是这样定义的。
要注意的是:由于参数的地址用于VA_START宏,所以参数不能声明为寄存器变量,或作为函数或数组类型。
使用VA_LIST应该注意的问题:
(1)因为va_start, va_arg, va_end等定义成宏,所以它显得很愚蠢,可变参数的类型和个数完全在该函数中由程序代码控制,它并不能智能地识别不同参数的个数和类型. 也就是说,你想实现智能识别可变参数的话是要通过在自己的程序里作判断来实现的.
(2)另外有一个问题,因为编译器对可变参数的函数的原型检查不够严格,对编程查错不利.不利于我们写出高质量的代码。
(1)因为va_start, va_arg, va_end等定义成宏,所以它显得很愚蠢,可变参数的类型和个数完全在该函数中由程序代码控制,它并不能智能地识别不同参数的个数和类型. 也就是说,你想实现智能识别可变参数的话是要通过在自己的程序里作判断来实现的.
(2)另外有一个问题,因为编译器对可变参数的函数的原型检查不够严格,对编程查错不利.不利于我们写出高质量的代码。
小结:可变参数的函数原理其实很简单,而VA系列是以宏定义来定义的,实现跟堆栈相关。我们写一个可变参数的C函数时,有利也有弊,所 以在不必要的场合,我们无需用到可变参数,如果在C++里,我们应该利用C++多态性来实现可变参数的功能,尽量避免用C语言的方式来实现。
示例代码:
#include<stdio.h>#include<stdarg.h>void simple_va_fun(int start,...){ va_list arg_ptr; int nArgValue = start; int nArgCount = 0; va_start(arg_ptr,start); do { ++nArgCount; printf("the %d the arg:%d\n",nArgCount,nArgValue); nArgValue=va_arg(arg_ptr,int); }while(nArgValue != -1); return; }main(){simple_va_fun(100,-1);simple_va_fun(100,200,-1);getchar(); }///////////////////int writeMultiString(void *c, ...){ va_list ap; const char *str; va_start(ap, c); str = va_arg(ap, const char *); while (str != NULL) { fputs(str, (FILE *)c); str = va_arg(ap, const char *); } va_end(ap); return 0;}
- VA_LIST 是在C语言中解决变参问题的一组宏
- C语言中: va_list 解决变参问题
- C语言中解决变参问题的几个宏
- va_list-关于方法变参的问题
- c语言变参函数的vsprintf与va_list的用法
- va_list解决c中变参问题
- C语言变参问题
- 解决变参数问题:va_list、va_start、vsnprintf、va_end的使用方法和实例
- C语言中可变参数的处理va_list
- C语言中可变参数的用法va_list
- C语言中##的用法以及##在变参的设计
- c 语言中, 如何让两个函数共用一组变量, 而在主程序中是不可见的?
- C语言的变参
- 数据结构和算法是解决C语言问题的关键!
- c语言va_list snprintf 的实现
- C语言找一组数中单独出现的数字
- C语言中,输出一组数的排列和组合
- C语言函数变参问题
- 基于时间段的Timer定时器执行任务
- QT程序全屏显示及消除鼠标指针
- 测试工具sgp_dd分析
- 让存储过程延时随机毫秒数,以防止同时接收到在线支付的反馈
- Oracle中将查询的结果放入一张自定义表中的例子
- VA_LIST 是在C语言中解决变参问题的一组宏
- PICT工具
- opencv下如何打印出一个三通道或者二通道矩阵
- 谈专利讲座后感
- TreeMap和TreeSet
- ubuntu 10.04 更改最大化 最小化 关闭 按钮 位置
- hdu 2104 hide handkerchief
- Express.js 中文入门指引手册
- 第十三周作业 2