C语言可变参数(va_list、va_start、va_end、va_arg)

在C语言中,va_list、va_start、va_end、va_arg这四个宏用于处理可变参数函数,它们构成了C语言可变参数列表的标准实现机制。

  1. va_list
    作用: 定义一个指向可变参数列表的指针类型
c 复制代码
#include <stdarg.h>
va_list ap;

va_list 是一个类型(typedef定义的)

实际上它是一个指向参数列表中某个位置的指针

通常声明为 va_list 类型的变量来保存参数列表信息

  1. va_start

作用: 初始化可变参数列表指针,使其指向第一个可变参数

va_start(va_list ap, last_fixed_param);

参数说明:

ap:要初始化的 va_list 变量

last_fixed_param:函数中最后一个固定参数的名称

示例:

c 复制代码
void my_printf(const char* format, ...) {
    va_list args;
    va_start(args, format);  // 初始化args,指向第一个可变参数
    
    // 使用args...
    
    va_end(args);  // 清理
}
  1. va_arg
    作用: 获取下一个可变参数的值
c 复制代码
type va_arg(va_list ap, type);

参数说明:

ap:可变参数列表指针

type:要获取的参数类型

示例:

c 复制代码
int sum(int count, ...) {
    va_list args;
    va_start(args, count);
    
    int total = 0;
    for (int i = 0; i < count; i++) {
        int value = va_arg(args, int);  // 获取下一个int类型的参数
        total += value;
    }
    
    va_end(args);
    return total;
}

// 调用:int result = sum(3, 10, 20, 30);  // 返回60
  1. va_end
    作用: 清理可变参数列表,释放资源
c 复制代码
va_end(va_list ap);

必须在函数结束前调用

使 va_list 指针失效

在某些平台上可能执行清理操作

完整示例

c 复制代码
#include <stdio.h>
#include <stdarg.h>

// 计算多个数的和
int add(int count, ...) {
    va_list args;
    va_start(args, count);
    
    int sum = 0;
    for (int i = 0; i < count; i++) {
        int num = va_arg(args, int);
        sum += num;
    }
    
    va_end(args);
    return sum;
}

// 打印字符串和数字
void print_info(const char* name, int count, ...) {
    va_list args;
    va_start(args, count);
    
    printf("Name: %s\n", name);
    printf("Numbers: ");
    for (int i = 0; i < count; i++) {
        int num = va_arg(args, int);
        printf("%d ", num);
    }
    printf("\n");
    
    va_end(args);
}

int main() {
    int result = add(4, 1, 2, 3, 4);
    printf("Sum: %d\n", result);  // 输出: Sum: 10
    
    print_info("Alice", 3, 10, 20, 30);
    // 输出:
    // Name: Alice
    // Numbers: 10 20 30 
    
    return 0;
}

注意事项

必须按顺序访问:使用 va_arg 时必须按照参数传递的顺序访问

类型匹配:va_arg 中指定的类型必须与实际参数类型一致

必须配对使用:va_start 和 va_end 必须成对出现

不能多次遍历:可变参数列表只能遍历一次

编译器依赖:这些宏的具体实现依赖于编译器和平台

这些宏是C语言实现可变参数函数的核心工具,广泛应用于标准库函数如 printf、scanf 等中。

相关推荐
老当益壮梁奶奶1 小时前
Linux软件编程学习笔记(二)Linux文件IO编程入门:从fopen到fgetc
linux·c语言·c++·笔记·学习
sunoo-2291 小时前
C 语言文件 IO 全攻略:从基础函数到实战踩坑(BMP 读取 + 词典查询)
linux·c语言·前端·笔记·vscode·学习
蒸蒸yyyyzwd1 小时前
cpp选手秋招学习笔记 day12
笔记·学习·oracle
Wang's Blog1 小时前
PostgreSQL笔记38:慢查询定位与优化的系统方法论
数据库·笔记·postgresql
XiaQ09192 小时前
Linux 常用命令学习笔记(用户管理篇):用户、组与权限的钥匙
linux·开发语言·笔记·学习
He BianGu2 小时前
【笔记】使用Assembly.LoadFrom和AssemblyLoadContext加载插件对比,以及有没有更合适的加载插件方案
笔记
hhwyqwqhhwy2 小时前
正点原子-ZYNQ7020 开发笔记
笔记
LuminousCPP2 小时前
栈和队列专题(四):LeetCode 232. 用栈实现队列|双栈分工 + 按需迁移 + 摊还 O(1)
c语言·数据结构·笔记·算法·leetcode
GGMM7892 小时前
富士 EP‑3957E‑C4 电源驱动板维修实战笔记
笔记·变频器·变频器维修
Wang's Blog2 小时前
PostgreSQL笔记37:数据库性能瓶颈排查方法论与工具链
数据库·笔记·postgresql