变长参数表

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!='\0';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("\n");
    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\n";
    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手册

posted on 2017-03-27 22:29  刘英皓  阅读(1149)  评论(0编辑  收藏  举报