【C/C++】可变长参数使用的方法

在Python里,有如下函数声明形式:

def f(n, *args) -> None:
    pass

其中,*args代表不定参数个数。

在C/C++中,有两种方式也可以实现变长参数的效果,下面直接给出实例并讲解。

 

第一种

void sum(int n, ...) {
	int* p = &n + 1;
	while (n--)
		cout << *p++ << endl;
}

在C/C++中,不管是stdcall还是_cdecl调用方式,函数参数都是自右向左压入栈中,栈空间在系统(包括但不限于Windows/Linux)内存中的布局可以看作一个倒放开口向下的盒子,每次往盒内放东西都会放到盒子最底部,而内存地址从盒子口往盒子底部依次递增,换言之,元素入栈时,其入栈地址是依次递减的;出栈时,地址是依次增加的。

综上所述,在传入参数的"..."部分,其元素与n的地址是递增的,即若n地址为0x8B,则"..."的地址依次为0x8E,0x92等。

显然,我们可以采用指针获得n的地址,然后将其后移,就能依次得到"..."内的参数值。

(ps:此种方法可能出现段错误)

其实数组也是类似的原理,数组头部有指针指向一块连续的内存区域,只是系统对其解读不同。

 

第二种

void sum(int start, ...) {
	va_list ap;
	__crt_va_start(ap, start);
	while (start--) {
		cout << &__crt_va_arg(ap, int) << endl;
	}
	__crt_va_end(ap);
}

第二种实质上就是系统对第一种方式的封装,不过我在__crt_va_arg(ap, int)前加上了一个取址符,好让大家看到打印出来的地址。

 

调用实例如下

int main()
{
	sum(5, 1, 2, 3, 4, 5);
	cout << endl;
    return 0;
}

 

代码在VS2019 MSVC环境下运行通过。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值