C语言可变参数列表(1)

尝试使用C语言可变参数列表


对于一些函数有的时候,我们不希望它只能传递固定参数,例如如果我们想计算2个整数数之和写一个int sum(int ,int );的函数,但是如果想计算3个数之和呢?n个数之和呢?不可能去定义无限多个函数,也不能让函数的参数太多,形如int sum(int ,int ,int ,int ,int ,int ,int ,int ,int ,int );10个数求和,这样的编码既不方便也不优雅,我们希望定义一个函数,实现参数个数可以任意变化而不影响程序功能的函数。这就需要C语言定义的可变参数列表来实现了。


可变参数列表的使用必须使用头文件  stdarg.h  该头文件包含有可变参数列表的宏定义和变量定义,包括va_list可变参数列表类型  va_arg()  va_start()  va_end()  3个宏定义


下面展示求和函数源代码:

#include<stdio.h>
#include<stdarg.h>  //包含有可变参数列表的宏定义
sum(int length,...)
{
int sum=0;  //求和的临时变量
va_list va; //可变参数列表变量


//指向values的下一个元素,在入栈规则下,这个元素为values右边第一个参数
va_start(va,length);    
while((length--)>0)   //values代表总共有多少个参数参与求和,不包括它本身
{
sum+=va_arg(va,int);   //迭代求和
}
va_end(va);  //使指针指向空防止未定义指针错误
return sum;   


}
int main()
{
printf("sum=%d",sum(10,2,3,4,5,2,3,4,5,64));
return 0;
}


原理

可变参数列表实际上是利用了C语言函数参数传递时的入栈顺序实现的,函数运行时,分配好的栈区的栈底在高地址,入栈向低地址扩展,地址减小(--),出栈则地址增加(++),调用函数时函数参数讲从右至左依次入栈,在本例中length就是最后一个入栈的地址最低,所以,只需要对length的地址进行自增运算,在保证所有参数类型一致的情况下即可把所有参数都访问到。

如本例:

va_list 定义一个可变参数列表的结构梯变量va_arg。

,然后使用va_start()这个带参宏来使va_arg结构体中的地址指向length之后的第一个参数的地址,在本例中就是参数2的地址。

然后我们就可以根据循环来迭代计算(栈空间是连续的)每次使用va_arg()这个带参宏来访问该元素,参数int是为了确定每次指针指向跳过的字节数。

最后,我们使用va_end()这个带参宏来使va结构体中的地址为NULL,防止为定义的行为发生。


所以,可变参数列表的原理就是简单的函数调用时参数在内存中存放规则(入栈规则)。


至于更复杂的printf(const char * format,...)可以接受不同类型的参数,是可变参数列表的经典实例。





未完待续!

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值