今天来了解一下C语言中的可变参数函数。
其实刚开始接触C语言的时候就碰到了,但是那个时候对函数、参数都没什么概念。我最早使用的可变参数函数是printf()。
下面来看看它的函数声明:
int printf(const char *format, ...);
再来举几个简单的例子:
printf("Hello, C!\n");
int a = 6;
printf("a = %d\n", a);
char str[] = "Nice to meet you.";
printf("%s\n", str);
int a, b, c, d;
a = b = c = d = 8;
printf("a = %d, b = %d, c = %d, d = %d\n", a, b, c, d);
上面这几个例子中分别使用了1个参数、2个参数、2个参数和4个参数。这种参数个数可以由用户定义的函数成为可变参数函数(variadic function)。可变参数函数需要包含至少一个强制参数,可变参数的参数类型可以变化。在上述示例中,参数1的类型始终为const char *,而参数2的类型分别为int,char *。
我们如果要声明一个可变参数函数,首先要包含头文件stdarg.h。
void function_name(int n, ...);
int example(int num, ...) {
int i;
int result = 0;
va_list vl;
va_start(vl, num);
for(i = 0; i < num; ++i) {
result = va_arg(vl, int);
printf("result: %d\n", result);
}
va_end(vl);
return result;
}
int main(int argc, char const *argv[]) {
example(5, 23, 45, 32, 34, 4);
return 0;
}程序的运行结果如下:

以下有几个宏:
va_list,创建参数列表(我理解它是个指针)。
va_start(),使va_list指向起始的参数。
va_arg(),根据第二个参数的类型(第二个参数为类类型)读取va_list指针中的内容,并将指针向后一个参数移动。
va_end(),释放va_list。
va_copy(),拷贝va_list的内容。

在VC++6.0中,va_list是结构体类型或者是char *类型。通过VC++6.0的类型提示可以看出,此时的va_list是char *。

感觉自己能用可变参实现的功能非常局限,那么printf()和scanf()函数族是怎么实现的呢?很好奇。