013 - C++引用

news2024/11/8 4:23:46

本期我们要讲的是 C++ 中的引用

上期我们讨论了指针,如果你没有看过那期内容,你一定要回去看看,因为引用实际上只是指针的扩展,你至少需要在基本层面上理解指针是如何工作的,然后才能继续学习本期的内容,本期内容是指针那一期的链接。

先了解这些

指针引用 是被大量翻来覆去提及的两个关键字,在 C++ 语言和其他语言中,它们本质上是一样的。

没错,指针和引用在计算机中做的事情几乎是一样的,从语义上说,我们如何使用和书写它们,有一些细微的区别,但从根本上来讲,引用只是指针的伪装,它们只是在指针的语法糖,它可以让程序更容易阅读,更容易被理解。

顾名思义,引用是一种我们引用现有变量的方式,不像指针。你可以创建一个新的指针变量或类似的东西,设它等于零,但是你不能对引用这样做,因为引用必须 “引用” 已经存在的变量。引用本身并不是新的变量,它们并不占用内存,它们没有真正的存储空间,它们不像典型的变量,因为它们是作为一个变量的引用而存在的。

下面我会举几个不同的例子来说明,例子会尽量简短一些,因为引用并不复杂,学习如何使用它们的最好方法就是随着系列的进行开始使用它们,后面我们会一直使用它们,你会看到一些很好的使用方式。

这就是引用

[igNo8b.png

我有一个变量,记作 a,我让它等于 5,它是一个整数,我给这个变量创建一个引用,我可以输入变量的类型,后面跟着 & 符号,注意 & 符号实际上是变量声明的一部分。

如果你看过指针那一期,你会知道我们可以使用 & 符号获取现有变量的内存地址,这里不一样,因为 & 符号实际 不在类型旁边,它只是类型的一部分,要注意区别,因为很多人只要看到 &,就认为都是引用,或者都是取地址,其实具体是啥取决于上下文,在当前例子中,因为它在类型的旁边,所以它是一个引用。

我们继续解释代码,我将基命名为 ref, 并将其值设为 a,然后这里就不需要其他奇怪的运算符了,我们只是让它等于一个现有的变量就可以了。

我们现在创造了一个叫做 别名 的东西,因为这个 ref “变量” ,——我说的 “变量” 是带引号的,因为它不是一个真正的变量,这只是一个引用,ref 变量实际上不存在,它只存在于我们的源代码中。如果你现在编译这段代码,你不会得到两个变量 a 和 ref,你只会得到 a。

我们现在能做的是,我们可以使用 ref 就像它就是 a,如果我们设 ref 等于 2,然后打印 a,你会发现 a 的值变为了2。

[igNSfd.png

因为 ref 就是 a,我们只是给 a 起了个别名,在这种情况下,我们的引用不是一个指针或其他类似的东西,编译器不需要实际创建一个新变量,如果你编译代码,这代码就相当于你设置了 a = 2,我们就是这么做的,因为如果给变量起一个别名的话,某些情况下我们的代码逻辑会更简单一些。

让我们尝试一些更复杂的东西。

我们定义一个函数 Increment,让整型变量递增。你觉的下面的写法会实现这个功能吗?

[igNsFq.png

并不能。

我们调用 Increment 函数,将 a 作为参数传递进去,你可以看到我们井没有把它作为一个指针或者引用等类似的东西传进去,它会拷贝这个值 5 复制到函数中,复制会创建一个全新的变量 value,这就是程序中发生的事情,如果运行代码我们可以看到打印出的值还是 5。

我们需要做的是通过引用来传递变量,这样它才会递增,因为我真正想做的是影响这个变量,那么我们该怎么做呢,如何通过将这个变量传递到函数中来修改它呢?

上期我们讨论了指针,还记得指针就是我们的内存地址吧,从理论上讲,我们可以做的是,可以没有将实际值 5 传递给函数,但是可以把 a 变量的内存地址传递进去,因为我们可以在这个函数中做的是可以查找那个内存地址,然后修改那个内存地址中的值。因为我们已经将该内存地址传递给了函数, 所以我们理论上是可以这样做的,所以需要怎么修改呢?采用指针。

[igNvYz.png

在调用函数 Increment 时我传入的是 a 的内存地址,而不仅仅是值 5;我做的另外一件事就是 逆向引用 value,这样我们就可以直接将值写入这个内存,而不是修改指针本身,如果我们在 value++ 之前不加 *,没有 dereference 操作符,那么它就会递增这个内存地址,而不是实际值。还有就是你会看到我在逆向引用后加了括号,因为优先级的关系,如果不加括号,它会先做 value++ 增量运算,然后再做逆向引用,但我们想做的刚好相反,是先做逆向引用,然后是增量运算。

如果我们编译代码,你会看到打印出了 6。我们成功地将变量传递到一个函数中。

本期是关于引用的,所以我们要用更加简单、更少的代码、更少的修饰语法来实现上面的过程。

简洁的引用

我会用一个引用来解决问题。

[igNJww.png

我重写了这个函数,使用引用代替指针,这样我们就不需要逆向引用了,然后我们就不要传递 a 的内存地址,只需要传递 a 即可,它是通过引用传递的。运行之后,效果和之前是完全一样的,不过这次的代码明显比之前的更漂亮,其实这也是唯一的区别了。

好了,这就是引用的全部了,它们只是语法糖,对于引用没有什么是指针不能做的,指针就像引用,不过它更有用,也更强大。然而,你可以使用引用的时候,就一定要用引用,因为它会让你代码更加简洁和简单,引用使得你的代码干净得多。

关于引用,我想提到的另一件重要的事情是, 一旦你声明了一个引用,你不能改变它引用的东西。

举个例子。

[igNKxa.png

编译当然可以通过,不过可不是你想的那个意思。它仅仅是把 a 的值变为了 b 的值,也就是 8。

这意味着如果你引用一个变量时,你需要把他赋值,你不能不赋值,编译器不会让你这么做的。你可以试一下。

当你声明一个引用时,必须马上给它赋值,因为他必须引用一些东西,时刻牢记它不是一个真正的变量,只是一个引用。

在这个例子中。如果我真的需要实现这种功能,——想改变引用的值,我该怎么做呢?

可以这样做

好吧,也有办法可以实现。

[igNLMx.png

首先它这不是一个真正的变量,我们需要先创建变量,然后设置它来指向 a,然后,我们更改为指向 b,当然,我老是说 “指向” 这个词,我们说的其实是指针,所以改一下,让我们把它作为一个指针,我们一开始可以把它设为 a 的内存地址,当我把指向变成了 b 时,我们需要 dereference (逆向引用)这个指针,然后给它赋值,在这个例子中我让 a 等于 2,b 等于 1,打印出来应该是 2 和 1,运行之后,你可以看到结果是对的。

后话

这就是我想说的关于引用的内容了,非常简单的东西,我们在未来会使用更多的引用操作,你以后会一直用它,像指针一样。随着这个系列的深入你会看到更多的例子。

本期就是这样,下期再见。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/411261.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

UI Toolkit(1)

UI ToolkitUI Toolkit界面画布设置背景制作UI布局UI Toolkit界面 在Unity 2021LTS版本之后UI Toolkit也被内置在Unity中,Unity有意的想让UI Toolkit 成为UI的主要搭建方式,当然与UGUI相比还是有一定的差别。他们各有有点,这次我们就开始介绍…

【Homebrew】MacBook的第二个AppStore

英文官网:Homebrew — The Missing Package Manager for macOS (or Linux) 中文官网:macOS(或 Linux)缺失的软件包的管理器 — Homebrew 1 简介 Homebrew 由开发者 Max Howell 开发,并基于 BSD 开源,是一…

基于K-最近邻算法构建红酒分类模型

基于K-最近邻算法构建红酒分类模型 描述 Wine红酒数据集是机器学习中一个经典的分类数据集,它是意大利同一地区种植的葡萄酒化学分析的结果,这些葡萄酒来自三个不同的品种。数据集中含有178个样本,分别属于三个已知品种,每个样本…

4.10-4.11学习总结

目录 MySql 关系型库数据 mysql启动方法 SQL通用语法 查询表 创建表 Mysql数据类型 表操作-修改 MySQL图形化界面 DCL 函数 约束 JDBC MySql 关系型库数据 建立在关系模型基础上,由多张相互连接的二维表组成的数据库 特点: 使用表存储数据,格式…

【C++】哈希(位图,布隆过滤器)

今天的内容是哈希的应用:位图和布隆过滤器 目录 一、位图 1.位图概念 2.位图的应用 二、哈希切分 三、布隆过滤器 1.布隆过滤器的概念 2.布隆过滤器的应用 四、总结 一、位图 1.位图概念 今天的内容从一道面试题开始引入: 给40亿个不重复的无符…

chapter-5 数据库设计

以下课程来源于MOOC学习—原课程请见:数据库原理与应用 考研复习 引言 设计的时候: 我们为什么不能设计成R(学号,课程号,姓名,所咋系,系主任,成绩)? 因为存在数据冗余…

BGP与OSPF混合组网

如图。R1和R2之间是OSPF Area 0,R23和R4之间是OSPF Area 1,R5和R6之间是OSPF Area2。除了R1和R2之间的cost是100,其余链路的cost都是10. AR1/2/3/4/5/6之间通过Loopback口建立IBGP全互联邻居关系,并且都是AS11520,和外部建立EBGP邻居访问100.100.100.1的网络。(不确定图中…

企业内训视频如何防范被盗录和下载?

企业内训视频如何防范被盗录和下载? 1. 【防下载】:实现视频文件的加密混淆、防下载; 2. 【防录屏】:A.(ID跑马灯防录屏)实现不同学员观看视频,实时显示该学员的姓名手机号时间;B.&…

线性代数 --- 最小二乘在直线拟合上的应用与Gram-Schmidt正交化(下)

在上一篇文章中,通过一个例子来说明最小二乘在拟合直线时所发挥的作用,也通过两个插图的比较进一步的阐明了投影与最小化e之间的密切关系。 线性代数 --- 最小二乘在直线拟合上的应用与Gram-Schmidt正交化(上)_松下J27的博客-CSD…

【UE Sequencer系列】08-副镜头切换、摄像机绑定摇臂的使用、摄像机绑定滑轨的使用

目录 一、副镜头切换 二、摄像机绑定摇臂的使用 三、摄像机绑定滑轨的使用 一、副镜头切换 1. 为“shot_05”新建镜头(复制资产,创建新的关卡序列) 同样的步骤再创建一个“Shot_07_02” 此时我们就可以对“Shot_07”中的两个副镜头进行切换…

最简单明了vite+ts+sass无loaders配置,利用ts读取scss文件中的变量并在App.vue中使用

做后端的,前端水平有限,最近练手,遇到了左侧菜单是展开关闭的问题,接触到了scss中定义全局变量,利用typescript读取的问题,在此记录一下 vitetssass 环境:package.json中内容如下,…

利用KMean算法进行分类

什么是KMean算法?简要说明什么是KMean算法,以及KMean算法的应用场景。 KMeans是一种聚类算法,它将数据集分成K个不同的类别(簇),使得每个数据点都属于一个簇,并且每个簇的中心点(质…

网络通信的安全性(HTTPS)

网络通信的安全性(HTTPS) 互联网是由无数网络节点组成的,两点之间的通信一般会经过很多个网络节点,因此,我们难免会有疑问: 作为发送方,我发送的消息内容会不会被中间人看到?&…

4.2 矩阵乘法的Strassen算法

1.伪代码以及用到的公式 ​ ​ ​ 2.代码 package collection; ​ public class StrassenMatrixMultiplication {public static int[][] multiply(int[][] a, int[][] b) {int n a.length;int[][] result new int[n][n]; ​if (n 1) {result[0][0] a[0][0] * b[0][0]…

为什么是毫末智行成为了DriveGPT的破壁人?

作者 | 魏启扬 来源 | 洞见新研社 毫末智行有着天生的紧迫感。 很多科技公司一年才举办一次的品牌日活动,毫末智行硬是办成了一个季度一次,活动频次的提高,则意味着组织内部新陈代谢的提速,从研发到落地乃至运营,都要…

ChatGPT 这个风口,普通人怎么抓住?

最近在测试ChatGPT不同领域的变现玩法,有一些已经初见成效,接下来会慢慢分享出来。 今天先给大家分享一个,看完就能直接上手的暴力引流玩法。 所需工具: 1)ChatGPT(最好是plus版,需要保证快速…

一个开源的大型语言模型LLaMA论文简单解读,LLaMA: Open and Efficient Foundation Language Models

一个开源的大型语言模型LLaMA论文解读,LLaMA: Open and Efficient Foundation Language Models返回论文和资料目录 1.导读 LLaMA 是 Meta AI 发布的包含 7B、13B、33B 和 65B 四种参数规模的基础语言模型集合,LLaMA-13B 仅以 1/10 规模的参数在多数的 …

ASEMI代理AD8638ARJZ-REEL7原装ADI车规级AD8638ARJZ-REEL7

编辑:ll ASEMI代理AD8638ARJZ-REEL7原装ADI车规级AD8638ARJZ-REEL7 型号:AD8638ARJZ-REEL7 品牌:ADI /亚德诺 封装:SOT-23-5 批号:2023 安装类型:表面贴装型 引脚数量:5 类型&#xff1…

初谈 ChatGPT

引子 最近,小编发现互联网中的大 V 突然都在用 ChatGPT 做宣传:“ChatGPT不会淘汰你,能驾驭ChatGPT的人会淘汰你”、“带领一小部分人先驾驭ChatGPT”。 确实,ChatGPT这个新生事物,如今被视为蒸汽机、电脑、iPhone 般的…

【ChatGPT 】国内无需注册 openai 即可访问 ChatGPT:ChatGPT Sidebar 浏览器扩展程序的安装与使用

一、前言 问题:国内注册 openai 账号麻烦,新必应有部分人也无法登录成功,存在域名单点登录失败等问题,所以无法真正使用 ChatGPT 解决:大部分人仅需使用 ChatGPT 的搜索功能,无需真正对话,需要…