欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

valist:解决变参问题

程序员文章站 2024-03-15 22:04:24
...

1. 概述

va_list 是在 C 语言中引入解决变参问题的一组宏,变参问题是指参数的个数不定或者每个参数的类型不同。

头文件:
#include <stdarg.h>

2. 使用步骤

va_list 是一个字符指针类型,在代码中可以理解成当前参数集的指针,下面是几个与 va_list 相关常见的函数

1. typedef char* va_list;

2. void va_start (va_list ap, prev_param);
   $ 对 va_list 进行初始化,将 ap 指针指向参数列表中的第一个参数
   $ 第一个参数是 va_list 指针,第二个参数变参前面紧挨的一个变量,即"..."之前的那个参数

3. void va_end(va_list ap);
   $ 释放指针,将输入的参数 ap 置为 NULL。
   $ 通常va_start和va_end是成对出现。

4. type va_arg(va_list ap, type); 
   $ 获取参数值,第一个参数 ap 指针,第二个参数是要获取的值类型
   $ 返回这个指定类型的值,然后把 ap 指针位置指向变参表中下一个参数的位置

以一个例子进行说明

(1) 当出现无法列出所有传递参数数目和类型的时候,用省略号指定参数列表

void PrintInt (int cnt, ...)

(2) 使用 va_list 获取参数并进行处理
- 定义一个 va_list 类型的变量,va_list 类型变量定义为 ap
- 调用 va_start,对 ap 进行初始化,让它指向可变参数表里面的第一个参数
- 使用 va_arg 获取参数,并使用参数
- 获取所有的参数之后,将 ap 指针关掉

void PrintInt(int cnt, ...)  { 
    va_list ap;
    int value;

    va_start(ap, cnt);

    for (int i = 0; i < cnt; i++) {
        value = va_arg(ap, int);
        printf("%d\n", value); 
    }

    va_end(ap);
}

(3) 调用变参函数

int main(void) {
    PrintInt(4, 1, 2, 3, 4);
}

输出结果为:

1
2
3
4

函数参数的传递原理

这里说明一下输出打印结果的原因,涉及函数参数的传递原理。

va_list 的实现原理过程中函数参数是以栈的形式存取,从右至左入栈。

参数的内存存放格式:参数存放在内存的堆栈段中,在执行函数的时候,从最后一个开始入栈。因此栈底高地址,栈顶低地址。

使用 va_arg 函数取出的时候从栈顶开始取,所以上面的例子中取出的第一个参数是 1.