0%

不定长参数

1. 介绍

使用特定函数操作不定长列表,初始化——操作——结束。

2. 具体

1
2
3
4
5
#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_start():初始化不定长参数列表类型aplast是不定长参数...之前挨着的一个已知类型参数。ap是自己声明的一个变量。必须在所有要用到ap的函数之前调用该函数。
  • va_arg(): 从ap依次取出相应的参数。应用需要从另外的地方知道不定参数的个数,比如printf()中的格式化字符串。如果下一个没有参数了,会返回随机错误。
  • va_copy(): 将src的不定参数列表复制到dest中,但要注意,不同系统实现方式不同,不要直接自己去操作ap列表,需要调用这些特定函数去操作。
  • va_end():最后结束了必须要调用这个。可以多次顺序调用va_start()va_end(),但必须成对儿。

man给出的例子:

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
#include <stdio.h>
#include <stdarg.h>

void
foo(char *fmt, ...)
{
va_list ap;
int d;
char c, *s;

va_start(ap, fmt);
while (*fmt)
switch (*fmt++) {
case 's': /* string */
s = va_arg(ap, char *);
printf("string %s\n", s);
break;
case 'd': /* int */
d = va_arg(ap, int);
printf("int %d\n", d);
break;
case 'c': /* char */
/* need a cast here since va_arg only
takes fully promoted types */
c = (char) va_arg(ap, int);
printf("char %c\n", c);
break;
}
va_end(ap);
}

3. 其他例子

宏中使用可变参数

1
2
#define haha(fmt, ...) \
vprintf(fmt, __VA_ARGS__)
1
2
#define haha(fmt, args...) \
vprintf(fmt, args)

函数中传递可变参数

1
2
3
4
5
6
7
8
9
void ss(fmt, ...)
{
va_list ap;

va_start(ap, fmt);
va_start(ap, fmt);
vprintf(fmt, ap);
va_end(ap);
}

4. 参考

  1. linux man手册