浅谈可变参数

可变参数

函数可以接受1个以上的任意多个参数(不固定)
先看一个例子
#include<stdio.h>
#include<stdlib.h>
#include<stdarg.h>

int avergae(int n, ...)//...表示参数是未知的
{
	va_list arg;//字符指针 typedef char* va_list;
	int i = 0;
	int sum = 0;
	va_start(arg, n);//把上面获得的字符指针,向后移动四个字节,跳过 n 的内存地址
	for (i = 0; i < n; i++)
	{
		sum = sum + va_arg(arg, int);//arg向后移动四个字节(sizeof(int)大小)
	}
	return sum / n;
	va_end(arg);//结束标志
}

int main()
{
	int a = 1;
	int b = 2;
	int c = 3;
	int avg1 = avergae(3, a, b, c);
	printf("平均数=%d\n", avg1);
	system("pause");
	return 0;
}


上述代码中
1.声明了一个va_list类型的变量arg,arg相当于一个指针,用来访问参数列表未知的部分。
2.指针arg是利用va_start来初始化的,使arg指向参数列表中的未知参数的第一个。
3.va_arg是用来访问参数列表中所有的未知参数的宏,该va_arg有两个参数,arg变量和所要访问的下一个未知参数的类型。va_arg返回这个未知参数的值,并且使arg指向下一个未知参数。
4.当访问完所有的未知参数是,调用va_end使变量arg为空指针。

可变参数列表

va_list arg; 转到定义 :typedef char* va_list; 重命名char* 为va_list。此处va_list就相当于 char*了,可以定义指针。
va_arg(arg, int); 转到定义: #define va_arg __crt_va_arg,__crt_va_arg
转到定义: #define __crt_va_arg(ap, t) ((t)((ap += _INTSIZEOF(t)) - _INTSIZEOF(t)))
ap表示可变参数指针,而t表示数据类型。
#define _INTSIZEOF(n) ((sizeof(n) + sizeof(int) - 1) & ~(sizeof(int) - 1))
(sizeof(int)-1),该表达式结果是3,当参数t为char时,’&’前面的表达式结果取最小值4,因此,两边表达式运算结果是4。
(*(t*)((ap += _INTSIZEOF(t)) - _INTSIZEOF(t)))。该表达式先让指针ap加上4字节的大小,再把减去4字节大小处所对应的值返回。用t强制类型转换,再解引用。注意此处t是传入参数的数据类型。
va_end(arg); 转到定义: #define va_end __crt_va_end,继续转到定义 :#define __crt_va_end(ap) ((void)(ap = (va_list)0)),由此看出,该语句把整型0强制转换为字符0, 然后传给指针ap,由此可知将ap清空。

可变参数限制

1.可变参数必须从头到尾的访问,可以半途停止,但不允许直接访问中间参数,
2. 参数必须要有一个命名参数;
3. 这些宏不能直接判断实际存在参数的数量,也无法判断每个参数的类型;


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值