c语言中函数中的参数,C语言中函数可变参数解析

大多数时候,函数中形式参数的数目通常是确定的,在调用时要依次给出与形式参数对应的所有实际参数。但在某些情况下希望函数的参数个数可以根据需要确定。典型的例子有

大家熟悉的函数printf()、scanf()

可变参数的实现:

C语言头文件stdarg.h提供了一个数据类型va-list和三个宏(va-start、va-arg和va-end),va—start使vp指向第一个可选参数。va—arg返回参数列表中的当前参数并使vp指向参数列表中的下一个参数。va

—end把vp指针清为NULL。函数体内可以多次遍历这些参数,但是都必须以va—start开始,并以va—end结尾。用它们在被调用函数不知道参数个数和类型时对可变参数表进行测试,从而为访问可变参数提供

了方便且有效的方法。va-list是一个char类型的指针,当被调用函数使用一个可变参数时,它声明一个类型为va-list的变量,该变量用来指向va-arg和va-end所需信息的位置。

下面给出va_list在C中的源码:

typedef char * va_list;

采用ANSI标准形式时,参数个数可变的函数的原型声明是:

type funcname(type para1, type para2, ...)

这种形式至少需要一个普通的形式参数,后面的省略号不表示省略,而是函数原型的一部分,type是函数返回值和形式参数的类型。

调用者在实际调用参数个数可变的函数时,要通过一定的方法指明实际参数的个数,例如把最后一个参数置为空字符串。

下面给出一个具体的例子:

求n个数的和:

int Sum(intn,...)

{int i = 0,sum = 0;

va_list vp;

va_start(vp,n); //va—start使vp指向第一个可选参数for (i=0; i

{

sum+=va_arg(vp,int);

}

va_end(vp); //va—end把vp指针清为NULL。returnsum;

}

printf函数实现:(此处只实现了基本类型的打印)

1 void my_print(const char *format,...)2 {3 char c = 0;4 va_list vp;5 va_start(vp,format); //vp指向第一个可选参数

6 while (*format)7 {8 c = *format;9 switch(c)10 {11 case '%':12 {13 char cc = *(++format);14 switch(cc)15 {16 case 'd':17 {18 char str[50];19 int n = va_arg(vp,int); //va—arg返回参数列表中的当前参数并使vp指向参数列表中的下一个参数。

20 char *string = _itoa(n,str,10); //把整数转为字符串

21 print_str(string);22 }23 break;24 case 'f':25 {26 char str[50];27 double f = va_arg(vp,double);//va—arg返回参数列表中的当前参数并使vp指向参数列表中的下一个参数

28 char *string = _gcvt(f,10,str);//将浮点型数转换为字符串,取四舍五入

29 print_str(string);30 }31 break;32 case 'c':33 putchar(va_arg(vp,char));34 break;35 case 's':36 {37 char *string = va_arg(vp,char*);38 print_str(string);39 }40 break;41 default:42 break;43 }44 }45 break;46 default:47 putchar(c);48 break;49 }50 format++;51 }

52  va_end(vp);

53 }

理解可变参数很重要的是要理解函数栈帧的创建与销毁,里面涉及到参数是如何压栈,这方面内容在前面的博客:http://www.cnblogs.com/zhonglongbo/p/8392026.html

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值