va_start 变参

我们常用的打印函数printf就是一个可变参数的函数,参数个数并不是固定的,函数原型为:

 

int printf(const char *format, ...);


这就是一个典型的变参函数,其中的变参用三个点 ... 表示。

那么该如何编写自己的变参函数呢,这就要用到处理变参的三个方法:va_start, va_arg, va_end , 这三个方法包含在头文件 stdarg.h 中,这三个方法的原型为:

 

 
  1. void va_start(va_list ap, last);

  2. type va_arg(va_list ap, type);

  3. void va_end(va_list ap);


下面用一个简单的代码来演示下:

 

 

 
  1. #include <stdio.h>

  2. #include <stdarg.h>

  3.  
  4. //求narg个整数的和

  5. int sum(int narg, ...)

  6. {

  7. va_list ap; //首先定义一个va_list类型的变量

  8. va_start(ap, narg); //va_start 的第一个参数为va_list变量,第二个参数为函数的最后一个固定参数

  9. int s = 0, i, tmp;

  10.  
  11. for(i = 0; i < narg; i++)

  12. {

  13. tmp = va_arg(ap, int); // 每次调用迭代出一个可变参数值, 该函数的第二个参数要求指明变量的类型

  14. s += tmp;

  15. }

  16.  
  17. va_end(ap); //用va_end结束迭代, ap is undefined

  18.  
  19. return s;

  20. }

  21.  
  22. int main(void)

  23. {

  24. printf("1+2 = %d\n", sum(2, 1,2));

  25. printf("1+...+5 = %d\n", sum(5, 1,2,3,4,5));

  26. printf("1+...+10 = %d\n", sum(10, 1,2,3,4,5,6,7,8,9,10));

  27. return 0;

  28. }


执行结果:

 

 
  1. 1+2 = 3

  2. 1+...+5 = 15

  3. 1+...+10 = 55


由于va_start函数的第二个参数是函数的最后一个固定参数名,所以C语言中的变参函数至少需要一个固定参数,如有需要,变参函数可以多次循环迭代出变参值:

 

 
  1. #include <stdio.h>

  2. #include <stdarg.h>

  3.  
  4. void myprint(int narg, ...)

  5. {

  6. va_list ap;

  7. char *str;

  8. int i;

  9.  
  10. va_start(ap, narg);

  11.  
  12. for(i = 0; i < narg; i++)

  13. {

  14. str = va_arg(ap, char *); //参数类型为char *

  15. printf("第 %d 个参数为:%s\n", i, str);

  16. }

  17.  
  18. va_end(ap);

  19.  
  20. printf("\n");

  21.  
  22. // 再循环取一次可变参数

  23. va_start(ap, narg);

  24.  
  25. for(i = 0; i < narg; i++)

  26. {

  27. str = va_arg(ap, char *); //参数类型为char *

  28. printf("第 %d 个参数为:%s\n", i, str);

  29. }

  30.  
  31. va_end(ap);

  32. }

  33.  
  34.  
  35. int main()

  36. {

  37. myprint(2, "hello", "world");

  38. return 0;

  39. }


执行结果:

 

 
  1. 第 0 个参数为:hello

  2. 第 1 个参数为:world

  3.  
  4. 第 0 个参数为:hello

  5. 第 1 个参数为:world


C语言中还提供了直接使用变参的函数,

 

 
  1. int vprintf(const char *format, va_list ap);

  2. int vfprintf(FILE *stream, const char *format, va_list ap);

  3. int vsprintf(char *str, const char *format, va_list ap);

  4. int vsnprintf(char *str, size_t size, const char *format, va_list ap);


只需传入va_list ap即可,不需要自己迭代参数值,例如

 

 
  1. #include <stdio.h>

  2. #include <stdarg.h>

  3.  
  4. void myprint(int narg, ...)

  5. {

  6. va_list ap;

  7. va_start(ap, narg);

  8.  
  9. vprintf("%s, %s \n", ap);

  10.  
  11. va_end(ap);

  12. }

  13.  
  14. int main()

  15. {

  16. myprint(2, "hello", "vprintf");

  17.  
  18. return 0;

  19. }


That's all!

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值