我们都用过 printf() 函数,函数的参数个数是不确定的,第一个参数一定是字符串。这种可变参数是如何实现的呢,我们今天就来学习下。
1 可变参数
首先,要实现可变参数必须依赖于头文件 stdarg.h。
其次,实现函数可变参数需要使用以下几个标示符:
- va_list:参数集合
- va_arg:取具体参数值
- va_start:标识参数访问的开始
- va_end:标识参数访问的结束
看了上面几个标示符完全不知道怎么用,没关系,下面通过一个例子讲解,就会明白。
2 实例分析
编写一个函数求 n 个数的平均值,将这 n 个数直接作为参数传递给函数。
// 44-1.c
#include<stdio.h>
#include<stdarg.h>
float average(int n, ...) // n表示要计算n个数的平均数
{
va_list args; // args是可变参数的集合
int i = 0;
float sum = 0;
va_start(args, n); // 标识参数访问的开始
for (i = 0; i < n; i++)
{
sum += va_arg(args, int); // 取具体的参数值,类型为int
}
va_end(args); // 标识参数访问的结束
return sum/n;
}
int main()
{
printf("%f\n", average(5, 1, 2, 3, 4, 5));
printf("%f\n", average(4, 1, 2, 3, 4));
return 0;
}
先看一下可变参数的限制:
- 可变参数必须从头到尾按照顺序逐个访问
- 参数列表中至少要存在一个确定的命名参数
- 可变参数函数无法确定实际存在的参数的数量
- 可变参数函数无法确定参数的实际类型
再来解读一下上面的代码:
1)参数列表中至少有一个确定的命名参数,这里的确定的参数是数字的数量,也就是 int 型的 n。类似的,printf() 函数中第一个参数永远是字符串,字符串中的 %d,%f,%p 等的数量用来确定有几个参数。
2)可变参数函数无法确定参数的实际类型,所以在取具体参数时使用 va_arg(args, int) 来确定参数为 int,在 printf 函数中使用 %d,%f,%s 等也是用来确定参数的类型。
注意:va_arg 中如果指定了错误的类型,那么结果时不可预测的。同样的在 printf() 函数中如果将%p 写成了 %d 得到的结果也是错误的。
3 小结
1、可变参数的函数提供了一种更方便的函数调用方式
2、可变参数必须顺序访问,无法直接访问中间的参数值