文章

【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 进行授权