C语言-可变参详解

#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;
*/

/*
可变参数的本质就是参数的入栈 强制参数指定栈的大小 可变参 依次入栈 

取值就是出栈的过程
*/

 


 

 

 

好好学习,天天向上。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值