C++ 算法考级专栏
真题分析、矩阵探测、递归回溯与基础语法
🎨 视觉封面【GESP】C++四级考试大纲知识点梳理, (5) 值传递
GESP C++四级官方考试大纲中,共有11条考点,本文针对第5条考点进行分析介绍。
(5)掌握函数参数的传递方式:C++值传递、引用传递、指针传递;Python 值传递、引用传递。 {: .prompt-info}
四级其他考点回顾:
一、什么是函数参数传递?
在调用函数时,如何把变量的值传递给函数内部,就是“参数传递方式”。C++中主要有三种:
| 类型 | 关键词 | 是否修改原变量 | 是否复制值 | 用途 |
|---|---|---|---|---|
| 值传递 | 无 | 否 | 是 | 安全,不改变原始数据 |
| 引用传递 | & |
是 | 否 | 高效,函数内部可修改原值 |
| 指针传递 | * 和 & |
是 | 否 | 多用于动态内存、数组等 |
二、值传递(Pass by Value)
📌 特点:
- 将变量的副本传给函数。
- 函数内部修改参数,不影响原始变量。
✅ 示例:
#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;
}
🧠 输出:
函数内x = 6
main中的a = 5
🎓 原理示意:
[main中的 a:5] --> 调用函数 --> 创建副本 x=5 --> 修改 x --> x=6
a 不变
三、引用传递(Pass by Reference)
📌 特点:
- 使用
&,传递变量的别名。 - 函数中修改参数,直接影响原变量。
✅ 示例:
#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;
}
🧠 输出:
函数内x = 6
main中的a = 6
🎓 原理示意:
[main中的 a] <--&x--> 函数参数 x:引用,不是副本,操作的是同一个变量
四、指针传递(Pass by Pointer)
📌 特点:
- 使用指针
*来传递变量地址。 - 函数中通过解引用
*修改原始值。
✅ 示例:
#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;
}
🧠 输出:
函数内x = 6
main中的a = 6
🎓 原理示意:
main中:
a = 5
&a = 地址0x1234
传给函数:
int* x = 0x1234
*x 就是访问地址中的值(即 a)
五、三者的对比总结
| 方式 | 用法 | 优点 | 缺点 |
|---|---|---|---|
| 值传递 | f(int x) |
简单安全 | 效率低,大对象慢 |
| 引用传递 | f(int &x) |
高效可修改 | 可能意外修改原值 |
| 指针传递 | f(int *x) |
可空指针,灵活 | 语法稍复杂 |
六、进阶思考 🤔
❓ 值传递会更安全吗?
是的,因为不会影响原始数据,适合做只读操作。
❓ 引用和指针有什么区别?
引用传递(Reference) 和 指针传递(Pointer) 的目标相似 —— 都能“修改原变量”,但用法、原理和表现有重要区别。
🧪 示例对比:
🎯 引用传递示例:
#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;
}
🎯 指针传递示例:
#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;
}
🔍 底层原理对比图解
✅ 引用传递:变量直接有一个“别名”
int a = 5;
int &ref = a;
// 等价于:
ref = a; // ref 不是新的变量,是 a 的另外一个名字
图示:
+-------+
| a |<--- ref(别名)
| 5 |
+-------+
✅ 指针传递:传递的是变量的地址
int a = 5;
int* ptr = &a;
// 通过解引用 *ptr 来访问/修改 a
图示:
+--------+ +-------+
| ptr | -----> | a |
|0x1234 | | 5 |
+--------+ +-------+
✅ 核心区别归纳
| 区别点 | 引用(int &x) |
指针(int *x) |
|---|---|---|
| 语法简洁性 | 更简单,更像普通变量 | 语法复杂,需要 *、& |
| 空指针风险 | 没有空引用 | 指针可能为 nullptr,需判断 |
| 可否重新绑定 | 不可以 | 可以重新指向其他变量 |
| 适合什么情况 | 只需要一个别名,提高效率 | 需要处理多个对象或动态数组时使用 |
| 与对象结合 | 常用于传对象避免拷贝开销 | 用于对象数组、链表、工厂模式等 |
🎯 实际开发中该用哪个?
| 场景 | 推荐方式 |
|---|---|
| 不希望修改原变量 | 值传递 |
| 只想高效传变量(特别是对象) | 引用传递 |
| 想修改原变量或多个变量 | 引用/指针 |
| 需要动态分配、传数组或链表 | 指针 |
| 函数返回多个结果(输出参数) | 指针(或引用) |
所有代码开源上传至 GitHub:yummy-code 仓库 · GESP 专题站:GESP WIKI
欢迎加入:C++ GESP/CSP 考级答疑群(688906745) 与 Java/Python交流群(982860385),点击可直接加群。
猜你想读 · 相关文章推荐
【GESP】C++四级考试大纲知识点梳理, (1) 指针
GESP C++四级官方考试大纲中,共有11条考点,本文针对第一条考点进行分析介绍。之前对1-3级大纲知识点的梳理思路是仅梳理编程基础知识考纲条目,对于C++编程本身语法和规则相关考纲要求,因为网上可查看的信息非常多,所以不做梳理。但目前来看,一方面系统梳理有利于孩子系统学习,另一方面感觉网上其他学习的同学也习惯针对考...
【GESP】C++四级考试大纲知识点梳理, (2) 结构体和二维数组
GESP C++四级官方考试大纲中,共有11条考点,本文针对第2条考点进行分析介绍。 (2)掌握 C++结构体、二维及多维数组的基本概念及使用 {: .prompt-info} 四级其他考点回顾: 【GESP】C++四级考试大纲知识点梳理, (1) 指针 {: .prompt-tip}
【GESP】C++四级考试大纲知识点梳理, (3) 模块化和函数
GESP C++四级官方考试大纲中,共有11条考点,本文针对第3条考点进行分析介绍。 (3)理解模块化编程思想,掌握函数的声明、定义及调用,掌握形参与实参的概念及区别。 {: .prompt-info} 四级其他考点回顾: - 【GESP】C++四级考试大纲知识点梳理, (1) 指针 - 【GESP】C++四级考试大纲...
OneCoder (lihongzheshuai)
一个中年人的自留地,记录学习 C++、GESP/NOI、Java、Python 与算法架构的心得体会。本站唯一网址:coderli.com