C语言:可变参数的函数(VA使用说明)
来源:互联网 发布:但丁数据 编辑:程序博客网 时间:2024/04/28 12:55
可变参数的函数(VA使用说明)
type va_arg( va_list arg_ptr, type );
void va_end( va_list arg_ptr );
void va_start( va_list arg_ptr, prev_param ); (ANSI version)
例子:
//include header file
#include <stdio.h>
#include <stdarg.h>
//函数声明
int average( int first, ... );
void main( void )
{
/* Call with 3 integers (-1 is used as terminator). */
printf( "Average is: %d\n", average( 2, 3, 4, -1 ) );
/* Call with 4 integers. */
printf( "Average is: %d\n", average( 5, 7, 9, 11, -1 ) );
/* Call with just -1 terminator. */
printf( "Average is: %d\n", average( -1 ) );
}
int average( int first, ... )
{
int count = 0, sum = 0, i = first;
va_list marker;
va_start( marker, first ); /* Initialize variable arguments. */
while( i != -1 )
{
sum += i;
count++;
i = va_arg( marker, int);
}
va_end( marker ); /* Reset variable arguments. */
return( sum ? (sum / count) : 0 );
}
//结果
Average is: 3
Average is: 8
Average is: 0
再看一个例子:
//include header file
#include <stdio.h>
#include <stdarg.h>
#define bufsize 80
#define buffer[bufsize];
/*
*格式化带参数的字符串
*/
int vspf(char *fmt, ... )
{
va_list argptr;
int cnt;
va_start(argptr,fmt);
cnt = vsnprintf(buffer,bufsize,fmt,argptr);//将带参数的字符串按照参数列表格式化到buffer中
va_end(argptr);//结束变量列表,和va_start成对使用
return cnt;
}
int main(int argc,char *argv[])
{
int inumber = 30;
float fnumber = 90.0;
char string[4] = "abc";
vspf("%d %f %s",inumber,fnumber,string);
printf("%s\n",buffer);
return 0;
}
原理分析:
代码:
void simple_va_fun(int i, ... )
{
va_list argptr;
int j=0;
va_start(argptr,i);
j=va_arg(argptr,int);
va_end(argptr);
printf("%d %d",i,j);
return;
}
simple_va_fun(100)
结果:100 -123456789(不确定值)
simple_va_fun(100,200)
结果:100 200
simple_va_fun(100,200,300)
结果:100 200
分析:(stdarg.h)
原始定义如下:
#define _INTSIZEOF(n) ( (sizeof(n) + sizeof(int) - 1) & ~(sizeof(int) - 1) )
#define va_start(ap,v) ( ap = (va_list)&v + _INTSIZEOF(v) )
#define va_arg(ap,t) ( *(t *)((ap += _INTSIZEOF(t)) - _INTSIZEOF(t)) )
#define va_end(ap) ( ap = (va_list)0 )
宏定义说明:
_INTSIZEOF(n)
这个宏定义主要是取得不变参数的长度(sizeof(n)).
(sizeof(n) + sizeof(int) - 1) &~(sizeof(int) - 1) 这种写法,主要目的是为了内存的对齐
#define va_start(ap,v) ( ap = (va_list)&v + _INTSIZEOF(v) )
这个宏定义,执行后,便可得到第一个可变参数的地址。说明如下:
C语言参数的压栈顺序是,从右向左,因此有如下的内存结构。
|高地址---------------------—|
|返回地址--------------------|
|。。。。。。----------------|
|可变参数前面的固定参数地址--|----->(va_list)&v
|第一个可变参数--------------|----->(va_list)&v + _INTSIZEOF(v)
|。。。。。。----------------|
|最后一个可变参数------------|
#define va_arg(ap,t) ( *(t *)((ap += _INTSIZEOF(t)) - _INTSIZEOF(t)) )
这个宏定义执行后,可以顺序得到可变参数的值。
说明:(ap += _INTSIZEOF(t)),这句话有两个地方需要注意:
注意一:ap+= ,实际上执行后 ap(即:可变参数的指针已经改变为了下一个可变参数的地址)
注意二:- _INTSIZEOF(t),执行减动作后,才得到你想要得到的地址。
这样做,有些复杂了。但是为了地址自加,且返回对应的值,这样做是合理的。
可参考keil中的这个宏定义实现方法:#define va_arg(ap,t) (((t *)ap)++[0])
#define va_end(ap) ( ap = (va_list)0 )
这个宏定义,目的只有一个,就是释放内存。
- C语言:可变参数的函数(VA使用说明)
- C语言中va(可变函数参数) 的另一种用法与危险事项
- C语言可变参数函数的实现
- C语言可变参数函数的实现
- C语言可变参数的函数
- C语言可变参数的函数实现
- C语言的参数可变函数
- C语言写参数可变的函数
- c语言函数的可变参数列表
- C语言函数的可变参数列表
- C语言可变参数函数的实现
- c 语言函数可变参数的处理
- C语言可变参数函数的实现
- c语言函数的可变参数列表
- C语言中可变参数的函数
- C语言“参数数量可变的函数”
- C语言实现参数个数可变的函数(转)
- C语言可变参数函数的使用技巧(转)
- Autocom CDP Pro for cars Activation, firmware update
- Android opengles 对GL10的封装 笔记(四)
- 微信是如何飞起来的(延伸阅读:性,微信下的机会?&一个超级用户的自白:移动社交那点事&类kik手机通信录互动应用前景探讨)
- 15周作业(3)
- POJ 3117 World Cup(我的水题之路——世界杯平局数目)
- C语言:可变参数的函数(VA使用说明)
- 给80后的10条宝贵买房建议 教您如何精明买房
- 执行jar包中的main方法
- C++写的字符窜处理类(源码)
- vc学习(一)单文档画圆,鼠标点击变色
- Adobe pdf professional 裁剪pdf页面
- Oracle 左连接与右连接
- 和自己的约定
- piwik安装过程