【GESP】C++四级考试大纲知识点梳理, (5) 值传递
GESP C++四级官方考试大纲中,共有11条考点,本文针对第5条考点进行分析介绍。
(5)掌握函数参数的传递方式:C++值传递、引用传递、指针传递;Python 值传递、引用传递。
四级其他考点回顾:
下面是一篇面向中小学生的 C++ 教学文章,围绕考试大纲中的知识点“掌握函数参数的传递方式:值传递、引用传递、指针传递”进行详细讲解,内容包括定义、用法、差异、原理等,并配有简单示例和可视化解释。
一、什么是函数参数传递?
在调用函数时,如何把变量的值传递给函数内部,就是“参数传递方式”。C++中主要有三种:
类型 | 关键词 | 是否修改原变量 | 是否复制值 | 用途 |
---|---|---|---|---|
值传递 | 无 | 否 | 是 | 安全,不改变原始数据 |
引用传递 | & | 是 | 否 | 高效,函数内部可修改原值 |
指针传递 | * 和 & | 是 | 否 | 多用于动态内存、数组等 |
二、值传递(Pass by Value)
📌 特点:
- 将变量的副本传给函数。
- 函数内部修改参数,不影响原始变量。
✅ 示例:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
#include <iostream>
using namespace std;
void addOne(int x) {
x = x + 1;
cout << "函数内x = " << x << endl;
}
int main() {
int a = 5;
addOne(a);
cout << "main中的a = " << a << endl;
return 0;
}
🧠 输出:
1
2
函数内x = 6
main中的a = 5
🎓 原理示意:
1
2
[main中的 a:5] --> 调用函数 --> 创建副本 x=5 --> 修改 x --> x=6
a 不变
三、引用传递(Pass by Reference)
📌 特点:
- 使用
&
,传递变量的别名。 - 函数中修改参数,直接影响原变量。
✅ 示例:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
#include <iostream>
using namespace std;
void addOne(int &x) {
x = x + 1;
cout << "函数内x = " << x << endl;
}
int main() {
int a = 5;
addOne(a);
cout << "main中的a = " << a << endl;
return 0;
}
🧠 输出:
1
2
函数内x = 6
main中的a = 6
🎓 原理示意:
1
[main中的 a] <--&x--> 函数参数 x:引用,不是副本,操作的是同一个变量
四、指针传递(Pass by Pointer)
📌 特点:
- 使用指针
*
来传递变量地址。 - 函数中通过解引用
*
修改原始值。
✅ 示例:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
#include <iostream>
using namespace std;
void addOne(int *x) {
*x = *x + 1;
cout << "函数内x = " << *x << endl;
}
int main() {
int a = 5;
addOne(&a);
cout << "main中的a = " << a << endl;
return 0;
}
🧠 输出:
1
2
函数内x = 6
main中的a = 6
🎓 原理示意:
1
2
3
4
5
6
7
main中:
a = 5
&a = 地址0x1234
传给函数:
int* x = 0x1234
*x 就是访问地址中的值(即 a)
五、三者的对比总结
方式 | 用法 | 优点 | 缺点 |
---|---|---|---|
值传递 | f(int x) | 简单安全 | 效率低,大对象慢 |
引用传递 | f(int &x) | 高效可修改 | 可能意外修改原值 |
指针传递 | f(int *x) | 可空指针,灵活 | 语法稍复杂 |
六、进阶思考 🤔
❓ 值传递会更安全吗?
是的,因为不会影响原始数据,适合做只读操作。
❓ 引用和指针有什么区别?
引用传递(Reference) 和 指针传递(Pointer) 的目标相似 —— 都能“修改原变量”,但用法、原理和表现有重要区别。
🧪 示例对比:
🎯 引用传递示例:
1
2
3
4
5
6
7
8
9
10
11
12
13
#include <iostream>
using namespace std;
void modify(int &ref) {
ref = 100;
}
int main() {
int a = 5;
modify(a);
cout << "a = " << a << endl; // 输出 100
return 0;
}
🎯 指针传递示例:
1
2
3
4
5
6
7
8
9
10
11
12
13
#include <iostream>
using namespace std;
void modify(int *ptr) {
*ptr = 100;
}
int main() {
int a = 5;
modify(&a); // 传地址
cout << "a = " << a << endl; // 输出 100
return 0;
}
🔍 底层原理对比图解
✅ 引用传递:变量直接有一个“别名”
1
2
3
4
5
int a = 5;
int &ref = a;
// 等价于:
ref = a; // ref 不是新的变量,是 a 的另外一个名字
图示:
1
2
3
4
+-------+
| a |<--- ref(别名)
| 5 |
+-------+
✅ 指针传递:传递的是变量的地址
1
2
3
4
int a = 5;
int* ptr = &a;
// 通过解引用 *ptr 来访问/修改 a
图示:
1
2
3
4
+--------+ +-------+
| ptr | -----> | a |
|0x1234 | | 5 |
+--------+ +-------+
✅ 核心区别归纳
区别点 | 引用(int &x ) | 指针(int *x ) |
---|---|---|
语法简洁性 | 更简单,更像普通变量 | 语法复杂,需要 * 、& |
空指针风险 | 没有空引用 | 指针可能为 nullptr,需判断 |
可否重新绑定 | 不可以 | 可以重新指向其他变量 |
适合什么情况 | 只需要一个别名,提高效率 | 需要处理多个对象或动态数组时使用 |
与对象结合 | 常用于传对象避免拷贝开销 | 用于对象数组、链表、工厂模式等 |
🎯 实际开发中该用哪个?
场景 | 推荐方式 |
---|---|
不希望修改原变量 | 值传递 |
只想高效传变量(特别是对象) | 引用传递 |
想修改原变量或多个变量 | 引用/指针 |
需要动态分配、传数组或链表 | 指针 |
函数返回多个结果(输出参数) | 指针(或引用) |
所有代码已上传至Github:https://github.com/lihongzheshuai/yummy-code
GESP各级别考纲要点、知识拓展和练习题目清单详见C++学习项目主页
“luogu-”系列题目已加入洛谷Java、C++初学团队,作业清单,可在线评测,团队名额有限,欢迎加入。
“bcqm-”系列题目可在编程启蒙题库进行在线评测。
本文由作者按照 CC BY 4.0 进行授权