6.2.2 传引用函数

练习6.11

void reset(int &i)
{
	i = 99;
}

int main() {
	int j = 42;
	reset(j);
	cout << "j = " << j << endl; //j=99
}

练习6.12

void reset(int &p, int &q)
{
	int a = p;
	int b = q;
	p = b;
	q = a;
}

int main() {
	int i = 42, j = 84;
	reset(i,j);
	cout << "i = " << i << endl;
	cout << "j = " << j << endl;
}

和指针交换差不多吧。

练习6.13
void(T),实参的初始值拷贝给变量,对变量的改动不会影响初始值。即传值调用不会改变实参。比如求阶乘的函数,fact函数中,尽管fact函数中val的值根据路径一直在改变,但是这个变动不会影响传入fact的实参,即调用fact(i)不会改变i的值。

void(&T)中的形参是引用类型,它将绑定到对应的实参上。此时改变T就是改变T所引对象的值。使用引用能够避免拷贝,比如有的类类型不支持拷贝操作的时候,就可以通过引用形参访问该类型的对象。

练习6.14
交换两个整数的值,需要用到引用,因为需要更改实参的值。如果没有用到引用,将没有发生交换:

void reset(int p, int q)
{
	int a = p;
	int b = q;
	p = b;
	q = a;
}
int main() {
	int i = 42, j = 84;
	reset(i,j);
	cout << "i = " << i << endl;
	cout << "j = " << j << endl;
}

在这里插入图片描述
另外,拷贝大的类类型对象或者容器对象比较低效,甚至有的类类型根本不支持拷贝操作。当某种类型不支持拷贝操作时,函数就只能通过引用形参访问该类型的对象。

而在阶乘函数中,不需要更改实参的值,不需要用到引用。

练习6.15
函数中不需要改变引用形参 &s的值,而且要避免拷贝string,因为它的值可能很长,因此为常量引用。
而occurs的值根据字符出现次数累加,会更改,因此不可能是常量引用,是普通引用。它是引用类型的形参而不是普通形参的原因是,因为返回值只有1个,是ret。那还需要返回出现的次数的话,只能通过绑定实参,更改实参的值来实现了。
字符的话,它不需要改变它的实参,也不需要返回,所以是一个普通的形参。
s是普通引用没有问题。
occurs不能是常量引用,因为在函数体中它出现在左值的位置,左值必须是可以修改的左值,而常量不能修改,所以错误。

auto index = find_char("hello world", 'o', ctr);

但是occurs是常量引用,没法更改这个值的情况下,不能累加出现的次数。错误。

string::size_type find_char(const string& s, char c, string::size_type& occurs)
{
	auto ret = s.size();
	occurs = 0;
	for (decltype(ret) i = 0; i != s.size();++i) {
		if (s[i] == c) {
			if (ret == s.size())
				ret = i;
			++occurs;
		}
	}
	return ret;
}
int main() {
	string s = "today";
	string::size_type ctr = 0;
	auto index = find_char(s, 'o', ctr);
	cout << index << endl; //第一次出现的位置是1
	cout << ctr << endl;   //总共出现1次
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值