变参函数(学习笔记)
1.首先我们要知道 函数参数是以栈的形式来存储的,从右到左。
举个例子 void func(int x, float y, char z);
调用函数的时候,实参 char z 先进栈,然后是 float y,最后是 int x,
因此在内存中变量的存放次序是 x->y->z。
从理论上说,我们只要探测到任意一个变量的地址,并且知道其他变量的类型,通过指针移位运算,则总可以顺藤摸瓜找到其他的输入变量。
2.那么怎么用自己的方式实现呢?
这里就要用到几个宏了
在这个#include <stdarg.h>
第一个 vs_start
对ap进行初始化,让ap指向可变参数表里面的第一个参数。
第一个参数是 ap 本身,第二个参数是在变参表前面紧挨着的一个变量,即“…”之前的那个参数
第二个 vs_arg
获取参数。它的第一个参数是ap,第二个参数是要获取的参数的指定类型。
按照指定类型获取当前参数,返回这个指定类型的值,然后把 ap 的位置指向变参表中下一个变量的位置;
第三个
va_end:释放指针,将输入的参数 ap 置为 NULL。通常va_start和va_end是成对出现。
第四个
va_list:一个字符指针,可以理解为指向当前参数的一个指针,取参必须通过这个指针进行。这个也是上文说的ap
代码实现
#include<stdio.h>
#include <stdarg.h>
void biancan(int count, ...);
int main(void){
biancan(4, 1, 2, 3, 4);
return 0;
}
//第一个参数定义可变参数的个数
//...所表示的多个形参 当函数调用的时候将会在栈区依次开辟连续空间进行存放的
void biancan(int count, ...){
va_list ap;
va_start(ap, count); //count 指向最后一个可变参数是我们自己知道count的指,然后把count赋值进去 ap指向第一个可变参数的地址
int i;int val;
for (i = 1; i <= count; i++) {
val = va_arg(ap, int); //va_arg(ap, int)的作用是从ap指向的可变参数列表中获取下一个int类型的值,并将ap指针向后移动到下一个可变参数的位置。
//返回的是获取到的int类型的值,而不是地址。
printf("第 %d 个参数: %d\n", i, val); //然后输出语句
}
printf("---------------\n");
va_end(ap); //释放
}