一、什么是可变参数列表?
在C语言中,我们知道当我们去实现一个函数时,它可以接受的参数是固定的,例如strcmp字符串比较函数,它有两个参数,传参时不能多传也不能少传。但是要想使我们的定义的函数可以接受多个参数,我们可以通过可变参数列表来实现。
可变参数列表可以通过宏来实现,这些宏是定义在头文件stdarg.h中的,它属于标准库的一部分。这些头文件中声明了一个类型va_list和三个宏,这三个宏分别是:va_start,va_arg和va_end。为了实现函数可以接受多个参数的功能,我们可以声明一个类型为va_list的变量,与这三个宏配合使用,访问参数的值。
接下来我们用定义一个求平均值的函数,然后使用可变参数列表来实现多个数求平均值的功能。
二、代码举例
#include<stdio.h>
#include<stdlib.h>
#include<stdarg.h>
int average(int n, ...)//其中的n表示可能传递的参数数量,省略号表示未确定的参数
{
va_list arg;
//char *arg;此处相当于定义了一个char*类型的指针,它用于参数列表未知的部分
int i = 0;
int sum = 0;
va_start(arg, n);
//上一句相当于(arg = (char *)&n + 4)其目的是取n得地址并且向后跳四个字节,此处是对arg进行初始化使它指向未知参数的第一个。
for (i = 0; i < n; i++)
{
sum += va_arg(arg,int);
//sum+=(*(int *)((arg+=4-4)通过指针arg每次向后跳四个指向下一个参数,这样就可以访问参数列表中所有的未知参数
}
return sum / n;
va_end(arg);
//arg=(char*)0;将 arg指针变为空指针
}
int main()
{
int num1 = 2;
int num2 = 4;
int num3 = 6;
int ret=average(3, num1, num2, num3);
printf("%d\n", ret);
system("pause");
return 0;
}
–上述代码中
1.声明了一个va_list类型的变量arg,arg相当于一个指针,用来访问参数列表未知的部分。
2.指针arg是利用va_start来初始化的,使arg指向参数列表中的未知参数的第一个。
3.va_arg是用来访问参数列表中所有的未知参数的宏,该va_arg有两个参数,arg变量和所要访问的下一个未知参数的类型。va_arg返回这个未知参数的值,并且使arg指向下一个未知参数。
4.当访问完所有的未知参数是,调用va_end使变量arg为空指针。
三、使用可变参数列表时需注意的事项
- 参数列表中至少要存在一个命名的参数
- 因为va_start,va_arg和va_end这些宏是无法识别参数的类型的,所以在使用时要指定正确的参数类型。
- 这些宏是无法确定实际的参数数量的,所以在传参时要将参数数量传过去
- 可变参数访问时是连续的。