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; } |
![](https://images2015.cnblogs.com/blog/705143/201703/705143-20170327222945404-1731446603.png)
本文由 刘英皓 创作,采用 知识共享 署名-非商业性使用-相同方式共享 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手册