c语言可变参数

1、基础认识

  C语言不同C++,Java等面向对象的语言一样具有重载功能。所以如果要在解决同名不同参数的函数上困难重重,变长参数意味着函数处理数据具有不确定性。即使是用C++重载也是一个繁琐的事情。

  C语言标准库<stdarg.h>定义了变长参数的使用。<stdarg.h>定义一个变量类型va_list和三个宏函数va_start(),va_arg(),va_end(),va_copy()。

  1)va_list ap:定义一个指向可选参数的指针ap。

  2)va_start(ap, valuec):初始化可变参数,使指针ap指向函数可变参数的第一个参数,同时valuec位于函数参数列表可变参数前的参数,确定可变参数的个数。

  3)va_arg(ap, type):逐个取出参数,type为参数的类型。

  4)va_end(ap):结束可变参数,释放资源。

  注意:可变参数一定要在函数参数列表的末尾,和默认参数一样。

 

 1 #include <stdio.h>
 2 #include <stdarg.h>
 3  
 4  int average(int, ...);
 5  
 6 int main()
 7 {
 8      printf("%d\n", average(5, 1, 2, 3, 4, 5));
 9 
10      return 0;
11 }
12 
13 int average(int valuec, ...) {
14 
15      int i, ave = 0;
16      va_list ap;   /* 定义va_list变量ap */
17      
18      va_start(ap, valuec);  /* 初始化变量ap */
19 
20      printf("%d\n", valuec);
21      printf("%d\n", ap);
22      
23      for(i = 0; i < valuec; i++) {
24           ave += va_arg(ap, int);  /* 取出参数 */
25      }
26      va_end(ap);  /* 结束变量ap */
27 
28      return ave / valuec;
29 }
30 
31 /*
32  * 输出3
33 */

  

  分析:由上面的例子可以知道可变参数的一般用法。

  猜想:va_list声明的指针ap。va_start(ap,valuec)使指针ap指向第一个可变参数。va_arg(ap,type)逐个取出参数,作指针运算。va_end(ap)释放资源,类似free(ap)。

  而va_copy(va_list dest, va_list src)复制src到dest。可以在va_start(ap, valuec)之后使用,类似复制指针。

 

2、进阶认识

1)在linux下man了一下函数va_copy()。发现一个函数例子:

 1 #include <stdio.h>
 2 #include <stdarg.h>
 3 
 4 void foo(char *, ...);
 5 
 6 int main()
 7 {
 8      char name[20] = "huangzijian";
 9      char a = 'a';
10      int i = 2333;
11      
12      
13      foo("scd", name, a, i);
14 
15      return 0;
16 }
17 
18 void foo(char *fmt, ...) {
19      va_list ap;
20      int d;
21      char c, *s;
22 
23      va_start(ap, fmt);
24      while (*fmt)
25           switch (*fmt++) {
26           case 's':              /* string */
27                s = va_arg(ap, char *);
28                printf("string %s\n", s);
29                break;
30           case 'd':              /* int */
31                d = va_arg(ap, int);
32                printf("int %d\n", d);
33                break;
34           case 'c':              /* char */
35                /* need a cast here since va_arg only
36                 takes fully promoted types */
37                c = (char) va_arg(ap, int);
38                printf("char %c\n", c);
39                break;
40           }
41      va_end(ap);
42 }
43 
44 /*
45  * string huangzijian
46  * char a
47  * int 2333
48 */

分析:上面的例子给了我们一个灵感,是否可以实现类似的printf和scanf函数。scanf函数容易实现,与上面如出一辙;但是printf函数就是在其他的字符上进行原字符输出。

 

转载于:https://www.cnblogs.com/MGT614469730/articles/5877230.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值