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

    可变参数列表


    头文件<stdarg.h>提供了遍历未知数目和类型的函数参数表的功能。该头文件的实现因不同的机器而不同,但提供的接口是一致的。
    假定函数 f 带有可变数目的实际参数,lastarg 是它的最后一个命名的形式参数(参数列表必须至少包括一个命名参数)。那么,在函数 f 内声明一个类型为 va_list 的变量 ap (argument pointer),它将依次指向每个实际参数。

    va_list ap;


    在访问任何未命名的参数前,必须用 va_start 宏初始化 ap 一次。(va_start 将最后一个命名参数作为起点,将 ap 初始化为指向第一个未命名参数的指针)

    va_start(va_list ap, lastarg);

    此后,每次执行宏 va_arg 都将返回一个参数,并将 ap 指向下一个参数。 va_arg 使用一个类型名来决定返回的对象类型、指针移动的步长。

    Type va_arg(va_list ap, Type);

    在所有的参数处理完毕之后,且在退出函数 f 之前,必须调用宏 va_end 以完成一些必要的清理工作。

    void va_end(va_list ap);

    Example


    下面以实现函数printf的一个最简单版本为例,介绍如何以可移植的方式编写可处理变长参数列表的函数。因为我们的重点在于参数的处理,所以,函数minprintf只处理格式字符串和参数,格式转换则通过调用函数printf实现。
    函数printf的正确声明形式为:

    int printf(char *fmt, ...)

    其中,省略号表示参数表中参数的数量和类型是可变的。省略号只能出现在参数表的尾部。
    因为minprintf函数不需要像printf函数一样返回实际输出的字符数,因此,我们将它声明为下列形式:

    void minprintf(char *fmt, ...)

    编写函数minprintf的关键在于如何处理一个甚至连名字都没有的参数表。

    #include <stdio.h>
    #include <stdarg.h>

    /* minprintf 函数:带有可变参数表的简化的printf函数 */
    void minprintf(char *fmt, ...)
    {
        va_list ap;  /* 依次指向每个无名参数 */
        char *p, *sval;
        int ival;
        double dval;

        va_start(ap, fmt);  /* 将 ap 指向第一个无名参数 */
        for (= fmt; *p; p++) {
            if (*!= '%') {
                putchar(*p);
                continue;
            }
            switch (*++p) {
                case 'd':
                    ival = va_arg(ap, int);
                    printf("%d", ival);
                    break;
                case 'f':
                    dval = va_arg(ap, double);
                    printf("%f", dval);
                    break;
                case 's':
                    for (sval = va_arg(ap, char *); *sval; sval++)
     putchar(*sval);
                    break;
                default:
                    putchar(*p);
                    break;
            }
        }
        va_end(ap); /* 结束时的清理工作 */
    }
  • 相关阅读:
    抽象工厂模式详解
    工厂方法模式详解
    简单工厂模式详解
    在IDEA中如何初始化Git,把项目推送到Git上
    Git报错解决:git@gitee.com: Permission denied (publickey).
    我为什么写博客?
    写什么样的博文
    Python装饰器的一点解读
    Python下将一般对象打印成Json
    众数的算法分析
  • 原文地址:https://www.cnblogs.com/qq78292959/p/2536459.html
Copyright © 2011-2022 走看看