#include<stdio.h>
#include<stdarg.h>
//windows下,栈是从高地址到低地址分配内存的
//函数传参就是入栈
//函数形参从右往左入栈,且栈是从高地址往低地址方向增长
/*
fun(5,4,3,2,1);
栈的内存
------------
|地址编号:5|
------------
|地址编号:4|
------------
|地址编号:3|
------------
|地址编号:2|
------------
|地址编号:1|
------------
当调用fun函数时 入栈顺序为 1,2,3,4,5 由于栈是从高地址往低地址方向增长
参数1存储在地址编号:5
参数2存储在地址编号:4
.......
参数5存储在地址编号:1
*/
void avrg(intarg_num,...);
int main(void){
avrg(40,1,2,3,5);
printf("avrg value is:\n");
return 0;
}
/*
*arg_num 强制参数,指定可变参的长度
*... 三个点,表示可变参数,要求传递的参数个数与强制参数指定的长度一致,可以不一致 但是你怎么遍历呢你不知道可变参长度哦,所以还是一致吧
*/
void avrg(int arg_num,...){
va_list valist;
int * p = &arg_num;
int i,val;
printf("valist参数未初始化的地址%d:\n",valist);
va_start(valist,arg_num);//初始化 valist的值使其指向可变参数的第一个参数的位置
printf("valist参数初始化后的地址%d:\n",valist);
printf("强制参数的地址:%d\n",&arg_num);
printf("初始化实际做的操作%d\n", (char*)&arg_num+_INTSIZEOF(arg_num));
for(i = 0; i<arg_num; i++){
printf("valist地址为:%d",valist);
val =va_arg(valist,int);//获取当前valist指向的值类型由第二个参数指定 并自动把valist移动到下个参数的位置
printf("--打印可变参第%d个参数,值为:%d\n",i+1,val);
}
va_end(valist);//清空valist指针 相当于 valist = (va_list)0; 其实调不调用无所谓 但是为了指针不瞎几把指还是调用下吧
}
/*
define in stdarg.h 宏函数定义如下
#define _INTSIZEOF(n) ( (sizeof(n) + sizeof(int) - 1) & ~(sizeof(int) - 1)
#define va_start(ap,v) ( ap = (va_list)&v + _INTSIZEOF(v) )
#define va_arg(ap,t) ( *(t *)((ap += _INTSIZEOF(t)) - _INTSIZEOF(t)) )
#define va_end(ap) ( ap = (va_list)0 )
typedef char* va_list;
*/
/*
可变参数的本质就是参数的入栈 强制参数指定栈的大小 可变参 依次入栈
取值就是出栈的过程
*/
好好学习,天天向上。