C语言可变参数是指函数的参数个数是不确定的,可以根据具体的需求接受可变数量的参数。例如,我们经常用到的 printf() 和 scanf() 函数就是可变参数函数,它们的函数原型为:
int printf(const char* format, ...);
int scanf(const char *format, ...);
其中,省略号 ... 表示可变参数列表。为了使用这个功能,我们需要使用 stdarg.h 头文件,该文件提供了实现可变参数功能的函数和宏。^1 具体步骤如下:
- 定义一个函数,最后一个参数为省略号,省略号前面可以设置自定义参数。
- 在函数定义中创建一个 va_list 类型变量,该类型是在 stdarg.h 头文件中定义的。
- 使用 int 参数和 va_start() 宏来初始化 va_list 变量为一个参数列表。宏 va_start() 是在 stdarg.h 头文件中定义的。
- 使用 va_arg() 宏和 va_list 变量来访问参数列表中的每个项。
- 使用宏 va_end() 来清理赋予 va_list 变量的内存。
常用的宏有:
- va_start(ap, last_arg) :初始化可变参数列表。ap 是一个 va_list 类型的变量, last_arg 是最后一个固定参数的名称(也就是可变参数列表之前的参数)。该宏将 ap 指向可变参数列表中的第一个参数。
- va_arg(ap, type) :获取可变参数列表中的下一个参数。ap 是一个 va_list 类型的变量, type 是下一个参数的类型。该宏返回类型为 type 的值,并将 ap 指向下一个参数。
- va_end(ap) :结束可变参数列表的访问。ap 是一个 va_list 类型的变量。该宏将 ap 置为 NULL 。
下面是一个简单的例子,演示了如何定义和使用可变参数函数:
#include <stdio.h>
#include <stdarg.h>
// 定义一个函数,计算多个整数的和
// 第一个参数是整数个数,第二个参数是提示信息,后面是可变数量的整数
int sum(int count, char *prompt, ...)
{
// 创建一个 va_list 类型的变量
va_list ap;
// 初始化 ap 指向第一个可变参数
va_start(ap, prompt);
// 输出提示信息
printf("%s\n", prompt);
// 定义一个累加器
int total = 0;
// 循环访问每个可变参数,并累加
for (int i = 0; i < count; i++)
{
total += va_arg(ap, int);
}
// 结束可变参数列表的访问
va_end(ap);
// 返回累加结果
return total;
}
int main()
{
// 调用 sum 函数,传入三个整数和提示信息
int result = sum(3, "The sum of three numbers is:", 10, 20, 30);
// 输出结果
printf("%d\n", result);
return 0;
}
输出结果为:
The sum of three numbers is:
60
有时候,我们可能不知道可变参数列表中每个参数的类型,而是通过固定参数来动态确定。例如 printf() 函数就是通过格式化字符串来指定每个可变参数的类型。这种情况下,我们需要在函数内部使用 switch-case 语句来根据固定参数的值来处理不同类型的可变参数。下面是一个例子,演示了如何根据格式化字符串来输出不同类型的可变参数:
#include <stdio.h>
#include <stdarg.h>
// 定义一个函数,根据格式化字符串来输出不同类型的可变参数
void print(char *fmt, ...)
{
// 创建一个 va_list 类型的变量
va_list ap;
// 初始化 ap 指向第一个可变参数
va_start(ap, fmt);
// 定义一个指针,指向格式化字符串
char *p = fmt;
// 循环遍历格式化字符串
while (*p != '\0')
{
// 如果遇到 % 符号,表示下一个字符是类型标识符
if (*p == '%')
{
// 指针后移一位
p++;
// 根据类型标识符,使用 switch-case 语句来处理不同类型的可变参数
switch (*p)
{
case 'd': // 整数类型
// 获取下一个可变参数,并输出
printf("%d", va_arg(ap, int));
break;
case 'f': // 浮点数类型
// 获取下一个可变参数,并输出
printf("%f", va_arg(ap, double));
break;
case 'c': // 字符类型
// 获取下一个可变参数,并输出
printf("%c", va_arg(ap, int));
break;
case 's': // 字符串类型
// 获取下一个可变参数,并输出
printf("%s", va_arg(ap, char *));
break;
default: // 其他类型,直接输出 %
printf("%%");
break;
}
}
else // 如果不是 % 符号,直接输出字符
{
printf("%c", *p);
}
// 指针后移一位,继续遍历
p++;
}
// 结束可变参数列表的访问
va_end(ap);
}
int main()
{
// 调用 print 函数,传入格式化字符串和可变参数
print("The result is: %d + %f = %f\n", 10, 3.14, 10 + 3.14);
print("Hello, %s! Your score is %d%%.\n", "Alice", 90);
return 0;
}
输出结果为:
The result is: 10 + 3.140000 = 13.140000
Hello, Alice! Your score is 90%.
这就是 C 语言可变参数的基本用法和原理。
系列文章持续更新,如果觉得有帮助请点赞+关注!