考纲要求
- 理解值传递是把实参的值复制给形参,函数内修改形参不影响实参。
- 掌握引用参数的写法,例如 int &x,函数内对它的修改会直接作用到实参。
- 能根据需求选择传递方式:只读计算用值传递,需要修改用引用传递。
- 知道数组作为参数传递时传递的是首地址,函数内修改元素会影响原数组。
典型题型
- 给出函数与调用,要求写出调用后变量的值。
- 把值传递函数改成引用传递,以满足修改实参的需求。
- 分析交换两个数的函数为什么没有生效。
常见错误
- 写 swap 时用值传递,函数内交换了形参,调用处的两个数没有任何变化。
- 以为引用传递会多复制一份数据,实际上形参与实参是同一个对象。
- 对不需要修改的参数也使用引用,增加误改风险。
- 把数组参数写成 int a[10] 并以为长度信息也被传入,实际长度需要另外传。
深入理解
值传递改不动外面
默认的参数传递是值传递:把实参的值复制给形参,函数里操作的是副本。所以这个经典写法不会交换成功:
void swap(int a, int b) { int t = a; a = b; b = t; }
int x = 1, y = 2;
swap(x, y); // x 仍是 1,y 仍是 2函数里确实交换了,但交换的是 a 和 b 这两个副本,函数一结束它们就消失了,外面的 x、y 从头到尾没被碰过。这是四级最高频的判断题。
加一个 & 就变成引用传递
把形参写成 int &a,a 就成了实参的别名,不是副本。对 a 做的任何修改都会直接作用到外面的变量上:
void swap(int &a, int &b) { int t = a; a = b; b = t; }
swap(x, y); // 这次交换成功「引用」在 C++ 里就是给已有变量起第二个名字,因此它必须在定义时绑定,不能先声明再绑定,也不能绑到常量上(除非加 const)。除了修改实参,引用还常用于避免大对象拷贝,例如传 string 或结构体时写成 const T &,既快又不会改到原值。
数组名传参是另一套规则
把数组传给函数时,传的不是整个数组,而是首元素的地址,所以函数里对数组元素的修改会真正影响到外面。正因为只传了地址,函数不知道数组有多长,必须额外传一个长度参数:
void fill(int a[], int n) {
for (int i = 0; i < n; i++) a[i] = 0;
}int a[] 和 int *a 在形参位置完全等价。这也解释了 sizeof(a) 在函数里得到的是指针大小而不是数组大小——这是很多人第一次遇到时想不通的地方。
自编例题
为什么值传递的交换不生效
比较下面两个交换函数的效果。
void badSwap(int a, int b) { int t = a; a = b; b = t; }
void goodSwap(int &a, int &b) { int t = a; a = b; b = t; }
int x = 1, y = 2;
badSwap(x, y); // x = 1, y = 2
goodSwap(x, y); // x = 2, y = 1badSwap 接收的是 x 和 y 的副本,函数内交换的只是形参 a 和 b,函数结束后副本被丢弃,x 与 y 保持原值。goodSwap 的形参是引用,a 和 b 分别绑定到 x 和 y 本身,函数内对它们的修改就是对外部变量的修改,所以交换生效。值传递传递的是值,引用传递传递的是同一个对象。考试里判断能否修改实参,看形参有没有加引用符号即可。
相关真题
这块内容在整条路线里的位置:GESP C++ 4 级备考路径。
READY TO START
开始练习
先做一套本级别测评,报告会指出哪些知识点需要重点补;再回到本页对照考纲要求逐条核对,把不确定的条目记下来集中练。
常见问题
引用参数和指针参数有什么区别?
引用参数写法更简单,使用时像普通变量,不能为空;指针参数需要解引用,可以为空指针,灵活性更高但更易出错。
字符串传参复制开销大吗?
值传递会复制整个字符串,内容长时开销明显。只读访问应使用 const string & 避免复制。
传数组时长度怎么处理?
数组名传参只传首地址,函数内拿不到长度,必须额外传一个长度参数,或者约定结束标记。
