zoukankan      html  css  js  c++  java
  • 变长参数表

    By francis_hao Mar 27,2017

    #include <stdarg.h>
    void va_start(va_list ap, last);
    type va_arg(va_list ap, type);
    void va_end(va_list ap);
    void va_copy(va_list dest, va_list src);

    调用函数必须声明一个va_list类型的变量,以供宏va_start(),va_arg()和va_end()使用。

    va_start()初始化va_list变量,参数last是变长参数表前的最后一个知道类型的变量名

    va_arg()获取下一个变长参数表里的参数,需要指定类型,以决定返回的对象类型和指针移动的步长

    va_end()是做最后的清理工作,在函数的最后使用,为什么要做清理man手册里并没有说,猜测是清除变长参数表占用的空间

    va_copy()可以复制va_list类型的变量,不过不是必须使用

    实例演示,来自K&R,做了一点修改

    #include <stdio.h>
    #include <stdarg.h>
    void self_printf(char *fmt, ...)
    {
        va_list ap;
        char *p;
        char *sval;
        int ival;
        va_start(ap,fmt);
        for (p=fmt;*p!='';p++){
            if(*p != '%'){
                putchar(*p);
                continue;
            }
            switch (*++p){ /*
    当前*p%*++p%后面的标识符 */
            case 's':
                sval=va_arg(ap,char *);
                printf("%s",sval);
                break;
            case 'd':
                ival = va_arg(ap,int);
                printf("%d",ival);
                break;
            default:
                putchar(*p);
                break;
            }
        }
        printf(" ");
        va_end(ap); /*
    需要进行清理 */
    }
    int main(void)
    {
        self_printf("self_printf %d",12);
        self_printf("self_printf %s","sval");
        return 0;
    }

     

    另一种类型的示例,关于变长参数表的宏定义,见【参考2】

    #include <stdio.h>
    #include <stdarg.h>
    #define print(fmt, ...) self_printf(fmt, ##__VA_ARGS__)
    void self_printf(char *s, ...)
    {
        va_list ap;
        va_start(ap, s);
        vprintf(s, ap);
        va_end(ap);
    }

    int main(void)
    {
        char *w = "world ";
        print("hello,%s",w);
        return 0;
    }

     

     


    本文由 刘英皓 创作,采用 知识共享 署名-非商业性使用-相同方式共享 3.0 中国大陆 许可协议进行许可。欢迎转载,请注明出处:
    转载自:http://www.cnblogs.com/yinghao1991/p/6629224.html

     

    参考

    【1】 K&R C程序设计语言 P136

    【2】 博客园 http://www.cnblogs.com/yinghao1991/p/6628815.html C语言预处理

    【3】 man手册

  • 相关阅读:
    linux 安装软件的方式
    git 基本操作
    交叉编译
    windows下 打印机打印操作类 VS2015
    VS2015 下 unicode 字符转换类
    C++ 多线程日志类的使用
    编译模板实例化
    C++中如何使用switch字符串
    linux下静态库与动态库
    jsoncpp 解码编码 中文为空 乱码问题
  • 原文地址:https://www.cnblogs.com/yinghao-liu/p/6629224.html
Copyright © 2011-2022 走看看