C语言可变参函数的实现原理浅析
2016-02-06 13:19
323 查看
先看一下可变参函数的使用:
int add(int n,...)
{
int i=0;
int result=0;
va_list arg=NULL;
va_start(arg,n);
for(;i<n;++i)
{
result+=va_arg(arg,int);
}
va_end(arg);
return result;
}
int main()
{
printf("%d\n",add(4,11,22,33,44));
}
以上是利用可变参函数求几个数的和的程序。从以上例子可以看到,可变参函数最大的特点就是参数的个数不确定,但可以正确的得到结果。下面看看可变参的实现原理吧。
参数在内存中的布局是这样的:
c语言默认的调用约定是__cdcel,参数从右往左进栈,在栈中也是连续的,所以只要知道了可变参的前一个参数,就可以得到下一个参数。上面的实现方式传进去了第一个参数,这个参数是所有参数的个数,所以程序就可以依次取出所有的参数了。下面看看可变参里几个宏定义的实现:
#define va_list void*
//让arg指向第一个参数的下一个位置,第一个参数是个数,也是开始位置
#define va_start(arg,n) (va_list)arg = (va_list)(((char*)&n)*sizeof(n))
//首先得到arg指向的内容,并让arg指向下一个参数,用当前参数的地址加上当前参数数据类型的大小
#define va_arg(arg,type) *((type*)arg); arg = ((char*)arg)+sizeof(type);
#define va_end(arg)
int add(int n,...)
{
int i=0;
int result=0;
va_list arg=NULL;
va_start(arg,n);
for(;i<n;++i)
{
result+=va_arg(arg,int);
}
va_end(arg);
return result;
}
int main()
{
printf("%d\n",add(4,11,22,33,44));
}
以上是利用可变参函数求几个数的和的程序。从以上例子可以看到,可变参函数最大的特点就是参数的个数不确定,但可以正确的得到结果。下面看看可变参的实现原理吧。
参数在内存中的布局是这样的:
c语言默认的调用约定是__cdcel,参数从右往左进栈,在栈中也是连续的,所以只要知道了可变参的前一个参数,就可以得到下一个参数。上面的实现方式传进去了第一个参数,这个参数是所有参数的个数,所以程序就可以依次取出所有的参数了。下面看看可变参里几个宏定义的实现:
#define va_list void*
//让arg指向第一个参数的下一个位置,第一个参数是个数,也是开始位置
#define va_start(arg,n) (va_list)arg = (va_list)(((char*)&n)*sizeof(n))
//首先得到arg指向的内容,并让arg指向下一个参数,用当前参数的地址加上当前参数数据类型的大小
#define va_arg(arg,type) *((type*)arg); arg = ((char*)arg)+sizeof(type);
#define va_end(arg)
相关文章推荐
- 快速排序---C语言实现
- c++拷贝函数
- [c++基础]valarray模板详解
- 栈的简单实现——使用C++容器库(STL Stack)
- C++面向对象编程:对象的内存分配与静态成员
- 1012. The Best Rank (25)
- C++动态调用DLL
- 理解C语言——从小菜到大神的晋级之路(8)——数组、指针和字符串
- C++ 经常使用类 string类
- C语言之数值计算--级数算法
- C语言之数值计算--级数算法
- C语言之数值计算--级数算法
- c++ 对象的互斥访问
- C 指针有害健康
- 一起talk C栗子吧(第一百二十一回:C语言实例--线程知识体系图)
- 【LeetCode】9. Palindrome Number
- c++n连环
- 第六届蓝桥杯C/C++B组第八题 移动距离
- C语言const的用法
- HDU 1010 深度搜索问题