valist:解决变参问题

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/qq_19923217/article/details/81385132

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.

猜你喜欢

转载自blog.csdn.net/qq_19923217/article/details/81385132