【C】——可变参数

  写代码之前要先介绍一下可变参数的备用知识; 

  C函数要在程序中用到以下这些宏:

void va_start( va_list arg_ptr, prev_param ); 
type va_arg( va_list arg_ptr, type ); 
void va_end( va_list arg_ptr );

 

  • 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引用的函数中正常返回。

  va在这里是variable-argument(可变参数)的意思.   
  这些宏定义在stdarg.h中,所以用到可变参数的程序应该包含这个头文件.下面我们写一个简单的可变参数的函数,改函数至少有一个整数参数,第二个参数也是整数,是可选的.函数只是打印这两个参数的值.

  了解了这些知识之后就可以写下我们的第一个可变参数的函数了;

 1 void myprintf(const char *format, ...)

 2 {

 3     va_list argp;        //定义保存函数参数的结构

 4     int argno = 0;        //记录参数个数

 5     char *para;        //存放取出的字符串参数

 6 

 7     va_start(argp, format);    //argp指向传入的第一个可选参数

 8 

 9     while(1)

10     {

11         para = va_arg( argp, char *);    //取出当前的参数,类型为char *

12         if(strcmp( para, "\0") == 0)

13             break;

14         printf("parameter  #%d is %s\n",argno,para);

15         argno++;

16     }

17     printf("format is %s\n",format);

18     va_end(argp);        //将argp置为NULL

19 }

  需要注意的是

  1. 函数定义的时候第二个参数必须是三个.;
  2. 必须用va_start宏初始化argp;
  3. 用完之后必须用va_end宏将argp置空;

  此函数的调用方法是: myprintf("printf","this","is","a","text","!","\0");//取\0为结束符 我们需要用一个字符'\0'来确定是否是最后一个字符;

  此函数是从第二个参数来输出的;那么第一个参数是用来干什么的呢?貌似第一个函数除了初始化的时候用到了,其他的时候都没有用到。我们再写一个函数来看看第一个参数的用处:

 1 void myprintf_two(int format, ...)

 2 {

 3     va_list argp;

 4     int argno = 0;

 5     int fora = format;

 6     char *para;

 7 

 8     va_start(argp,format);

 9     while(fora--)

10     {

11         para = va_arg(argp,char *);

12         printf("parameter  #%d %s\n",argno,para);

13         argno++;

14     }

15     printf("format is %d\n",format);

16     va_end(argp);

17 

18 }

  哦,原来第一个参数可以是int类型的;这下了解了第一个函数的用处了吧@!

  在用可变参数函数的时候需要注意一点,就是在获取float类型的时候一定要用double接收;来看个函数:

 1 double add(int n, ...)

 2 {

 3     va_list argp;

 4     va_start(argp,n);

 5     double sum = .0;

 6     while(n--)

 7         sum += va_arg(argp,double);

 8     va_end(argp);

 9     return sum;

10 }

  如果把va_arg(argp,double)改成:va_arg(argp,float)就会报错了:

【C】——可变参数

  就这么多吧,附上完整的代码:

【C】——可变参数
 1 #include <stdio.h>

 2 #include <string.h>

 3 #include <stdarg.h>

 4 

 5 void myprintf(const char *format, ...)

 6 {

 7     va_list argp;        //定义保存函数参数的结构

 8     int argno = 0;        //记录参数个数

 9     char *para;        //存放取出的字符串参数

10 

11     va_start(argp, format);    //argp指向传入的第一个可选参数

12 

13     while(1)

14     {

15         para = va_arg( argp, char *);    //取出当前的参数,类型为char *

16         if(strcmp( para, "\0") == 0)

17             break;

18         printf("parameter  #%d is %s\n",argno,para);

19         argno++;

20     }

21     printf("format is %s\n",format);

22     va_end(argp);        //将argp置为NULL

23 }

24 

25 void myprintf_two(int format, ...)

26 {

27     va_list argp;

28     int argno = 0;

29     int fora = format;

30     char *para;

31 

32     va_start(argp,format);

33     while(fora--)

34     {

35         para = va_arg(argp,char *);

36         printf("parameter  #%d %s\n",argno,para);

37         argno++;

38     }

39     printf("format is %d\n",format);

40     va_end(argp);

41 

42 }

43 

44 double add(int n, ...)

45 {

46     va_list argp;

47     va_start(argp,n);

48     double sum = .0;

49     while(n--)

50         sum += va_arg(argp,double);

51     va_end(argp);

52     return sum;

53 }

54 

55 int main(void)

56 {

57     myprintf("printf","this","is","a","text","!","\0");    //取\0为结束符

58     myprintf_two(4,"this","is","a","text");

59     printf("sum(10,20) = %g\n",add(2,10.0,20.0));

60     return 0;

61 }
View Code

 

 

你可能感兴趣的:(可变参数)