zoukankan      html  css  js  c++  java
  • 【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)
    13             break;
    14         printf("parameter  #%d is %s
    ",argno,para);
    15         argno++;
    16     }
    17     printf("format is %s
    ",format);
    18     va_end(argp);        //将argp置为NULL
    19 }

      需要注意的是

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

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

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

     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
    ",argno,para);
    13         argno++;
    14     }
    15     printf("format is %d
    ",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)就会报错了:

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

     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)
    17             break;
    18         printf("parameter  #%d is %s
    ",argno,para);
    19         argno++;
    20     }
    21     printf("format is %s
    ",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
    ",argno,para);
    37         argno++;
    38     }
    39     printf("format is %d
    ",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","!","");    //取为结束符
    58     myprintf_two(4,"this","is","a","text");
    59     printf("sum(10,20) = %g
    ",add(2,10.0,20.0));
    60     return 0;
    61 }
    View Code

      利用 vsnprintf 配合 va_list 操作传递进来的参数:

    #include <stdio.h>
    #include <stdarg.h>
    int mon_log(char* format, ...)
    {
    char str_tmp[50];
    int i=0;
    va_list vArgList;                            //定义一个va_list型的变量,这个变量是指向参数的指针.
    va_start (vArgList, format);                 //用va_start宏初始化变量,这个宏的第二个参数是第一个可变参数的前一个参数,是一个固定的参数
    i=_vsnprintf(str_tmp, 50, format, vArgList); //注意,不要漏掉前面的_
    va_end(vArgList);                            //用va_end宏结束可变参数的获取
    return i;                                    //返回参数的字符个数中间有逗号间隔
    }
    //调用上面的函数
    void main() 
    {
        int i=mon_log("%s,%d,%d,%d","asd",2,3,4);
        printf("%d
    ",i);
    }
  • 相关阅读:
    2019年CSP-J初赛试题(普及组)试题详解
    开放课件
    猴子选大王 (约瑟夫问题)
    后缀表达式转中缀表达式
    JDBC的使用
    JDBC
    MySQL第五天
    MySQL第四天
    MySQL第三天
    MySQL第二天
  • 原文地址:https://www.cnblogs.com/ngnetboy/p/3148652.html
Copyright © 2011-2022 走看看