变参函数和va_list
来源:互联网 发布:k30平板荷载试验算法 编辑:程序博客网 时间:2024/06/05 12:23
此乃讨论贴。首先介绍下我的理解。变参函数参数看起来是这样
<函数返回值类型> 函数名 (固定形参1,固定形参2,...)比如
声明
void multiply (int factor1, int factor2, ...)
函数体
void multiply (int factor1, int factor2, ...)
{
}
在调用他的函数里
multiply(1,2,3,4); /*多少都行,但必须至少是2个,因为声明里固定参数有2个*/
多出来的两个参数,需要用到一种特殊的数据类型来访问(也有其他方法)
void multiply (int factor1, int factor2, ...)
{
va_list ap; /* va_list 类型变量ap,其实木有啥,就是一正常的指针类型变量,赋值后应该是指向参数列表,以后个就用ap指针来访问变参了,跟其他指针 * 类型变量声明一样,他现在没有指向任何地方*/
va_start (ap, factor2); /* ap现在指向 factor2后面的一个参数了,va_start作用只是指针ap赋值这里小啰嗦一下,va_start赋值时,应当是指向最后一个固定参数(这里 * 是factor2,factor1是第一个固定参数)因为只有变参才需要指针访问他,固定参数直接用参数名就好了嘛*/
int factor3 = *((int *)ap);
factor3 = va_arg(ap, int); /* 这两种方法factor3值相同,不同的是va_arg返回的值是ap当前,并且将ap指向下一个参数,通过的方法是*ap++ */
...
va_end(ap) /* ap再也不用了*/
}
最近查阅了几个博文关于变参函数和va_list 的使用,发现有一些矛盾之处。
首先是堆栈中参数存储顺序。根据
http://blog.csdn.net/zckloveczy/article/details/4260698
高地址 最后一个参数
倒数第二个参数
...
第一个参数
函数返回地址
低地址 函数体
然后根据
http://wenku.baidu.com/view/e79b720f52ea551810a68783.html
高地址 函数返回地址
最后一个参数
倒数第二个参数
...
低地址 第一个参数
这两处矛盾在于函数返回地址和参数列表比,谁的地址更高?
第二个有趣的现象是,va_end 这个宏,我觉得他应该是像delete一样,先把指针删了,再指向null,可代码中,他什么都没有做。并且当我用完va_end(ap)后,用*((int *)ap)居然能看到他的值
在VC++6.0的include有一个stdarg.h头文件,有如下四个宏定义:
#define _INTSIZEOF(n) ((sizeof(n)+sizeof(int)-1)&~(sizeof(int) - 1) )
/* int型占的字节数,不大于4的是4,大于4小于等于8的是8 */
#define va_start(ap,v) ( ap = (va_list)&v + _INTSIZEOF(v) )
/* v是最后一个固定参数,加上他按int字节数对齐后,就是第一个可选参数地址 */
#define va_arg(ap,t) ( *(t *)((ap += _INTSIZEOF(t)) - _INTSIZEOF(t)) )
/* 第一步ap += _INTSIZEOF(t),ap指向下一个形参,命名为n,第二步,将当前参数的值返回 */
#define va_end(ap) ( ap = (va_list)0 ) // 将指针置为无效
在内核的文件里
#define va_arg(ap, T) (*(T *)(((ap) += (_bnd (T, _AUPBND))) - (_bnd (T,_ADNBND))))
#define va_end(ap) (void) 0
#define va_start(ap, A) (void) ((ap) = (((char *) &(A)) + (_bnd (A,_AUPBND))))
- 变参函数和va_list
- 用va_list实现变参函数
- 有关VA_LIST的用法--变参函数的实现
- 有关VA_LIST的用法--变参函数的实现
- C++ 变参va_list 示例
- 变参数print函数的实现va_list
- va_list-关于方法变参的问题
- c语言变参函数的vsprintf与va_list的用法
- vsprintf函数和va_list用法
- C语言中: va_list 解决变参问题
- vsprintf函数和va_list用法详解
- vsprintf函数和va_list用法详解
- vsprintf函数和va_list用法详解
- C++变参函数和变参宏
- 解决变参数问题:va_list、va_start、vsnprintf、va_end的使用方法和实例
- 有关va_list和vsnprintf输出函数的问题
- 有关va_list和vsnprintf输出函数的问题
- 有关va_list和vsnprintf输出函数的问题(可变参数)
- js正则表达式的特殊字符
- 《百家讲坛》之战国七雄
- [网络流] 最大流 最小费 回顾
- 质因数:arcane number1
- (二)上传图片至服务器,写入到数据库Blob字段中,以及从数据库读取Blob信息(iframe父子页面传值)
- 变参函数和va_list
- portage一些概要
- ajax之服务器端的 JSON
- Linux定时器的使用
- 《jsp连接数据库大全》
- group by havding order by
- ios中的图标
- 图形验证码生成工具类
- js正则表达式大全