C 标准库 stdarg.h

  • Post category:C

C 标准库 stdarg.h 头文件提供了一个参数列表的访问函数支持,即函数的可变长参数。这意味着编写不定数量和类型参数的函数成为可能。本文将详细介绍 stdarg.h 的功能和用法。

1. stdarg.h 原理

通常情况下,我们定义一个 C 函数时,需要在声明中定义这个函数所需要的参数,参数名和类型。例如:

int myFunction(int arg1, double arg2, char * arg3);

但有时候我们需要定义一个不定数量的参数,而这些参数数量和类型都是在函数被调用时才能确定的,这时候我们就可以使用可变长参数函数。可变长参数函数通过一个名为 va_list 的列表数据类型来实现这种不定数量参数的支持。在 stdarg.h 头文件中,va_list 是一个代表参数列表的类型。

例如,在使用可变长参数函数时,先定义一个 va_list 变量,然后初始化该变量为参数列表的开头,并使用 va_arg 函数来访问列表中的参数。当访问完所有的参数后,需要使用 va_end 函数将 va_list 让出。可变长参数的函数需要在声明中加上省略号 ...,如下所示:

#include <stdarg.h>

int myFunction(int arg1, double arg2, char * arg3, ...) {
    va_list args;                // 定义 va_list 类型变量
    va_start(args, arg3);        // 将 args 指向 arg3 后面的参数
    int value1 = va_arg(args, int);    // 访问参数列表
    double value2 = va_arg(args, double);
    // 依次访问每个参数
    va_end(args);                // 清除参数列表并让出 va_list

    // 函数正常逻辑
    return 0;
}

2. stdarg.h 示例

下面,我们来看两个使用 stdarg.h 的简单示例,演示可变长参数函数的基本用法。

示例一

#include <stdarg.h>
#include <stdio.h>

void printNumber(int count, ...) {
    va_list numbers;
    va_start(numbers, count);

    for (int i = 0; i < count; i++) {
        int number = va_arg(numbers, int);  // 从参数列表依次读取整型数据
        printf("%d\n", number);
    }

    va_end(numbers);
}

int main() {
    printNumber(3, 1, 2, 3);    // 输出 1 2 3
    printNumber(4, 10, 20, 30, 40); // 输出 10 20 30 40
    return 0;
}

在上面这个示例中,我们定义了一个 printNumber 函数,它支持任意数量的整型数据。通过使用 va_list,我们可以依次从参数列表中取出每一个传入的整数,然后将其输出。

示例二

#include <stdarg.h>
#include <stdio.h>

double average(double baseValue, int numberOfValues, ...) {
    double sum = baseValue;
    va_list values;
    va_start(values, numberOfValues);

    for(int i = 1; i <= numberOfValues; i++) {
        sum += va_arg(values, double);  // 从参数列表依次读取双精度浮点型数据
    }

    va_end(values);    // 清空可变列表

    return sum / (double)(numberOfValues + 1); // 计算平均值
}

int main() {
    printf("平均值是 %f\n", average(10.0, 3, 20.0, 40.0, 60.0));
    return 0;
}

在上面这个示例中,我们定义了一个 average 函数,它接受一个初始值,和任意数量的双精度浮点型数据,并计算这些值的平均数。

对于可变长参数函数而言,参数的类型必须有固定的大小,例如 doubleint 等简单数据类型。对于更复杂的类型,例如结构体或指针,则需要使用其他技术来传递。

到此为止,希望本文能对大家正确、全面了解并使用 stdarg.h 提供帮助,谢谢阅读!