变长参数列表

用到了以下三个宏(第四个宏只是与之相关,并没用到):

  void va_start(va_list arg_ptr, prev_param); 

  type va_arg(va_list arg_ptr, type); 

  void va_end(va_list arg_ptr);

  void va_copy(va_list d, va_list s);

va_list:用来保存宏va_start、va_arg和va_end所需信息的一种类型。为了访问变长参数列表中的参数,必须声明va_list类型的一个对象,它的定义:
  typedef char * va_list;
va_start:访问变长参数列表中的参数之前使用的宏,它初始化用va_list声明的对象,初始化结果供宏va_arg和va_end使用;
va_arg: 展开成一个表达式的宏,该表达式具有变长参数列表中下一个参数的值和类型。每次调用va_arg都会修改用va_list声明的对象,从而使该对象指向参数列表中的下一个参数;
va_end:该宏使程序能够从变长参数列表用宏va_start引用的函数中正常返回。

下面是示例代码:

 1 #include <stdio.h>
 2 #include <string.h>
 3 #include <stdarg.h>
 4 
 5 /* ANSI标准形式的声明方式,括号内的省略号表示可选参数 */
 6 int demo(char *msg, ...)
 7 {
 8     va_list arg_list = NULL;        // 定义保存函数参数的结构,实际上是字符串
 9     int count        = 0;           // 纪录参数个数
10     char* para       = NULL;        // 存放取出的字符串参数
11     
12     /* argp指向传入的第一个可选参数,msg是最后一个确定的参数 */  
13     va_start(arg_list, msg);
14     
15     while (1) 
16     {  
17         /* 取出当前的参数,类型为char*                               */
18         /* 一般自定的变长参数函数,变长部分类型都是统一的               */
19         /* 如果想编写类似与printf这种参数类型不固定的变长参数的函数      */
20         /* 那么就需要在参数中说明参数的类型,例如%d表示整数,%s表示字符串 */
21         para = va_arg(arg_list, char *);
22         
23         /* 采用空串指示参数输入结束,这是必须,函数需要知道参数列表的结尾 */  
24         if (0 == strcmp(para, "\0"))
25         {
26             break;
27         }
28                                      
29         printf("Parameter #%d is: %s\n", count, para);
30         count++;
31     }  
32     
33     /* 完成清理工作 */
34     va_end(arg_list);
35     
36     return 0;  
37 }
38 
39 int main(void)  
40 {  
41     demo("DEMO", "This is a demo!", "You are so cute ^_^!", "\0");
42     
43     return 0;
44 }
45 
46 /*
47     输出结果:
48     Parameter #0 is: This is a demo!
49     Parameter #1 is: You are so cute ^_^!
50 */
原文地址:https://www.cnblogs.com/wendellyi/p/3081479.html