第二节 · 以不变应万变 · 深入参数与返回值
在上一节中,我们初步认识了函数——一段有名字的、可重复使用的代码。现在,让我们更深入地了解函数的参数和返回值。
函数就像一台机器:你往里面放入原料(参数),它经过加工处理,产出成品(返回值)。而这台机器处理原料的方式,以及产出成品的形式,都大有讲究。
参数传递的方式
当我们调用函数时,实参的值是如何传递给形参的呢?C++ 提供了几种不同的传递方式。
值传递
这是最基本的传递方式。调用函数时,实参的值会被复制一份给形参:
void addOne(int n)
{
n = n + 1;
cout << "函数内 n = " << n << endl;
}
int main()
{
int x = 10;
addOne(x);
cout << "函数外 x = " << x << endl;
return 0;
}输出结果:
为什么 x 的值没有改变?因为传递给函数的只是 x 的一个副本,函数内部修改的是这个副本,而不是 x 本身。这就像你把一份文件复印一份给别人,别人在复印件上涂改不会影响你的原件。
引用传递
如果我们希望函数能够修改实参的值,可以使用引用传递:
输出结果:
在形参类型后加上 &,表示这个参数是一个引用。引用可以看作是原变量的一个别名,对引用的操作就是对原变量的操作。
指针传递
我们也可以通过传递指针来实现类似的效果:
指针传递和引用传递的效果类似,但语法上有所不同。引用在使用时更加自然,而指针更加灵活(比如可以为空、可以重新指向其他对象)。
常量引用
有时候,我们想通过引用传递来避免复制的开销,但又不希望函数修改参数的值。这时可以使用常量引用:
const 关键字表示这个引用是只读的,函数内部不能通过它修改原变量。这样既避免了复制的开销,又保证了数据的安全。
对于基本类型(如 int、double),值传递的开销很小,通常直接用值传递即可。但对于较大的对象(如 string、vector),使用常量引用可以显著提高效率。
返回值
函数可以返回一个值给调用者。返回值的类型在函数声明时指定:
如果函数不需要返回任何值,可以将返回类型声明为 void:
返回引用
函数也可以返回引用:
返回引用时要特别注意:不要返回局部变量的引用,因为局部变量在函数结束后就会被销毁:
多个返回值
C++ 的函数只能返回一个值,但如果我们需要返回多个值怎么办?
方法一:使用引用参数
方法二:返回结构体或类
方法三:使用 pair 或 tuple(C++11)
数组作为参数
数组名在传递给函数时,实际上传递的是数组首元素的指针。因此,函数内部无法知道数组的长度,需要额外传递一个参数:
以下三种声明方式是等价的:
理解参数传递和返回值的机制,对于编写高效、正确的程序至关重要。在实际编程中,我们需要根据具体情况选择合适的传递方式。
习题
编写一个函数
swap,交换两个整数的值。分别使用引用和指针两种方式实现。编写一个函数,接收一个整数数组,返回数组中的最大值和最小值。
Last updated