news 2026/10/2 2:33:12

C++ 第 14 课:引用

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
C++ 第 14 课:引用

上一课标准答案:

  1. 最后输出:
5

因为change(x)只是把x的值复制给参数a,函数里改的是副本。

  1. 依次输出:
13 3

原因是函数内部:

number += 10;

把副本number从 3 改成 13,所以先输出 13。

但外面的:

x

没有改变,仍然是 3。

  1. 因为:
void change(int a)

采用的是值传递。a是x的副本,不是x本身。

  1. 一句话:

值传递就是把外部变量的值复制一份给函数参数,函数修改副本不会影响原变量。


第 14 课:引用&

这一课非常重要。

前面我们遇到的问题是:

void change(int a) { a = 100; } int main() { int x = 5; change(x); std::cout << x << std::endl; }

最终:

x = 5

因为:

x → 复制一份 → a

但现在我就是想让函数:

直接修改原来的x

怎么办?

C++ 可以使用:

&

这就是:

引用 reference


1. 先看效果

把:

void change(int a)

改成:

void change(int& a)

完整代码:

#include <iostream> void change(int& a) { a = 100; } int main() { int x = 5; change(x); std::cout << x << std::endl; return 0; }

这次输出:

100

为什么只增加了一个:

&

结果就完全不一样?


2. 值传递:给你一张复印件

以前:

void change(int a)

可以想象成:

main: x ┌─────┐ │ 5 │ └─────┘ │ │ 复制 ▼ change: a ┌─────┐ │ 5 │ └─────┘

所以:

a = 100;

只改变下面那个盒子:

x = 5 a = 100

3. 引用:不是复印,而是给原变量起“别名”

现在:

void change(int& a)

可以把a理解成:

x的另一个名字。

调用:

change(x);

之后可以粗略想象成:

┌─────────┐ x ─────→│ 5 │ └─────────┘ ↑ │ a

这里:

x

和:

a

不是两个盒子。

而是:

两个名字,指向同一个变量。

所以:

a = 100;

其实就是在改:

x = 100;

最终外面的x也变了。


4. 最重要的对比

值传递

void change(int a)

含义:

给函数一个副本

修改:

a

不会影响原变量。


引用传递

void change(int& a)

含义:

让参数 a 直接代表原来的变量

修改:

a

原变量也会变化。


5.&到底放在哪里?

看:

int& a

现在先把它整体理解成:

a是一个int类型的引用。

不是:

int a

而是:

int& a

多了:

&

这告诉 C++:

不要创建新的整数副本,a要引用外面的那个整数。


6. 一个简单例子

void addOne(int& number) { number++; }

然后:

int main() { int count = 10; addOne(count); std::cout << count << std::endl; }

执行:

count = 10

调用:

addOne(count);

此时:

number

就是count的引用。

然后:

number++;

实际上修改:

count:10 → 11

所以最后输出:

11

7. 机器人例子:真正修改速度

上一课我们写:

void stopMotor(double speed) { speed = 0.0; }

这个不能改变外面的速度。

现在改成:

void stopMotor(double& speed) { speed = 0.0; }

然后:

int main() { double motor_speed = 100.0; stopMotor(motor_speed); std::cout << motor_speed << std::endl; }

最后:

motor_speed = 0

这次是真的改到了原变量。


8. 用“遥控器”来理解引用

值传递像:

拍了一张机械臂当前状态的照片给函数。

函数在照片上画来画去,不影响真实机械臂。

引用则像:

把真实机械臂的控制权交给函数。

函数一修改:

speed = 0;

真实外部变量也改变。

这个区别你以后一定要记住。


9. 引用本身也可以在普通代码里创建

不只是函数参数可以用引用。

例如:

int x = 5; int& y = x;

这里:

y

是:

x

的引用。

可以理解成:

x ─────┐ ▼ ┌──────┐ │ 5 │ └──────┘ ▲ y ─────┘

所以:

y = 20;

以后:

x = 20 y = 20

因为它们实际上对应同一个东西。


10. 看完整程序

#include <iostream> int main() { int x = 5; int& y = x; y = 20; std::cout << x << std::endl; std::cout << y << std::endl; return 0; }

输出:

20 20

11. 引用不是“复制值”

这一点特别关键。

int x = 5; int y = x;

和:

int x = 5; int& y = x;

完全不同。

第一种:

int y = x;

得到两个变量:

x = 5 y = 5

之后:

y = 100;

结果:

x = 5 y = 100

互不影响。


第二种:

int& y = x;

y是x的引用。

执行:

y = 100;

结果:

x = 100 y = 100

12. 引用创建时通常必须绑定变量

例如:

int x = 5; int& y = x;

这里创建y的同时就告诉它:

你引用x。

不能像普通变量那样随便理解成:

int& y;

然后以后再说引用谁。

对于普通引用,通常创建时就必须绑定目标。

现在先记住这一点即可。


13. 引用一旦绑定,通常不能“换人”

看:

int x = 5; int z = 10; int& ref = x;

这里:

ref

绑定的是:

x

如果后面写:

ref = z;

初学者可能以为:

ref 改成引用 z。

不是。

实际上是:

把z的值赋给ref所引用的x。

因为:

z = 10

所以:

x 变成 10

引用本身仍然是x的别名。

这个以后再深入。


14. 为什么 C++ 需要引用?

最直接的原因有两个。

第一:需要修改外部变量

例如:

void reset(double& angle) { angle = 0.0; }

第二:以后处理很大的对象时,避免复制

比如以后你有:

std::vector<double>

里面可能有大量数据。

如果每次传函数都完整复制一份,会浪费时间和内存。

所以以后经常会看到:

void process(std::vector<double>& data)

甚至:

void process(const std::vector<double>& data)

这里又出现了:

const

以后我们会专门学。

现在只需要知道:

引用不仅能修改外部变量,还能避免不必要的数据复制。


15. 真实机械臂代码会经常见到

以后可能看到:

void updateJointAngle(double& angle)

或者:

void calculateIK(double x, double y, double z, double& joint1, double& joint2, double& joint3)

这里前三个:

x y z

可能只是输入。

而:

joint1 joint2 joint3

使用引用,是因为函数需要把计算结果直接写出去。

例如:

joint1 = 30.0; joint2 = 45.0; joint3 = -20.0;

那么外部对应的关节变量也会改变。


16. 一个简单的 IK 风格例子

先不管真实运动学,只模拟:

void calculateAngles(double& joint1, double& joint2) { joint1 = 30.0; joint2 = 45.0; }

然后:

int main() { double j1 = 0.0; double j2 = 0.0; calculateAngles(j1, j2); std::cout << j1 << std::endl; std::cout << j2 << std::endl; }

输出:

30 45

因为:

joint1 引用 j1 joint2 引用 j2

函数直接修改了:

j1 j2

17. 参数是值还是引用,只差一个&

非常值得对比。

值传递

void change(int a)
复制

引用传递

void change(int& a)
直接操作原变量

所以你以后看到函数参数:

double angle

和:

double& angle

一定要意识到:

行为可能完全不同。


18. 一个非常重要的安全意识

引用很方便,但也意味着函数可以修改你的原变量。

例如:

void test(int& x) { x = -999; }

外面:

int motor_speed = 100; test(motor_speed);

结果:

motor_speed = -999

所以以后看到:

&

要多一个意识:

这个函数有没有可能修改我传进去的变量?

这对阅读真实工程代码非常重要。


19. 今天先不要把&和“地址”混在一起

你可能以后会听说:

& 可以取地址

确实如此。

但是同一个符号:

&

在不同位置可能有不同含义。

今天我们只学习:

int& a

这里的&表示:

引用

“取地址”我们学习指针时再讲,否则现在很容易混乱。


20. 本课核心图

值传递:

x ┌───┐ │ 5 │ └───┘ │ │复制 ▼ a ┌───┐ │ 5 │ └───┘

引用:

x ───┐ ▼ ┌─────┐ │ 5 │ └─────┘ ▲ a ───┘

这个图如果真正理解了,引用就掌握一半了。


本课小练习

第 1 题

void change(int& a) { a = 20; } int main() { int x = 5; change(x); std::cout << x << std::endl; }

最终输出什么?

第 2 题

int x = 10; int& y = x; y = 30;

最后:

x = ? y = ?

第 3 题

下面两种写法有什么本质区别?

void test(int a)

和:

void test(int& a)

第 4 题

void setZero(double& angle) { angle = 0.0; }

如果:

double joint1 = 45.0; setZero(joint1);

最后joint1是多少?

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/10/2 2:31:35

Flink CDC 3.5.0 从理论到实践 —— 第 10 章 作业运维与监控

Flink CDC 3.5.0 从理论到实践 —— 第 10 章 作业运维与监控 课程定位:本系列教程以 MySQL 为唯一数据源,Sink 覆盖 Doris / Paimon / Kafka 三大目标,从原理到生产落地,全链路实战。 版本基线:Flink CDC 3.5.0 + Flink 1.20.x + MySQL 8.0/8.4 + Doris 4.1 + Paimon 1.4…

作者头像 李华
网站建设 2026/10/2 2:29:59

DFT签核流程与质量门(Sign-off Quality Gate)

DFT签核流程与质量门(Sign-off & Quality Gate) 面向IC测试工程师的DFT签核方法论与工程实战指南。本文系统阐述DFT签核流程、质量门体系、常用EDA工具链、自动化回归脚本与CI流水线,覆盖从检查项设定到流片风险量化的全链路实践。 一、DFT签核概述 1.1 签核的必要性 在…

作者头像 李华
网站建设 2026/10/2 2:29:36

60个AI短剧运镜术语:从定场、对话到情绪、动作、收尾全拆解

运镜&#xff0c;是AIGC里翻车率最高的&#xff0c;没有之一。截图张张能看&#xff0c;一连播就露馅&#xff1a;角色钉在原地&#xff0c;镜头小幅晃&#xff0c;像给静态图加了呼吸特效。你写“电影质感、缓缓推进、高级氛围感”&#xff0c;AI听完一脸懵&#xff0c;最后给…

作者头像 李华