var_list

C语言中如果参数个数不定,可以用省略号传参

1
var func(parm_list, ...)

printf 也是用了这种传参方式。
函数传参的时候用到了栈的数据结构,参数从右往左一个一个入栈。所以理论上,知道一个参数的类型和其中一个的地址,就可以知道所有参数。

1
2
3
4
5
6
7
8
//var_list 是char*类型,定义一个var_list
var_list args;
//var_list 初始化
var_start(args, parm_list);
//调用var_arg ,返回type类型变量
var_arg(args, type);
//获取所有参数之后,以防发生危险,需要把args指针置为NULL
var_end(args);

可以看一个简单printf的例子

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
#include <stdio.h>
#include <stdarg.h>
void myprintf(const char *format, ...)
{
va_list ap;
char c;
va_start(ap, format);
while (c = *format++) {
switch(c) {
case 'c': {
/* char is promoted to int when passed through '...' */
char ch = va_arg(ap, int);
putchar(ch);
break;
}
case 's': {
char *p = va_arg(ap, char *);
fputs(p, stdout);
break;
}
default:
putchar(c);
}
}
va_end(ap);
}
int main(void)
{
myprintf("c\ts\n", '1', "hello");
return 0;
}