C++入门篇(3)---引用

1.引用

        你有没有被人起过外号?比如身边的朋友,喊他的时候不会叫他的全名,像我很好的朋友,我一般都喜欢叫他"阿威",而不会去称呼全名.我叫他"阿威",他还是他没有什么问题.

        这里新登场的引用不是新定义一个变量,而是给已存在变量取了一个别名,编译器不会为引用变量开辟内存空间,它和它引用的变量共用同一块内存空间.

下面我们来细说:

        1.1引用的概念

用法:

        类型& 引用变量名(对象名) = 引用实体;

从图中我们可以看出b不仅和a的值相同,地址也是一模一样!这是为什么?

这里要注意的一点是:引用类型必须和引用实体是同种类型的!

这里编译器直接就报错了,这样是不被允许的!

        1.2引用的特性

1. 引用在定义时必须初始化

        这里的引用a没有初始化,编译器直接报错了!

2. 一个变量可以有多个引用

        此时这些引用都是n的别名,指向的就是n,和n共用一块空间!

3. 引用一旦引用一个实体,再不能引用其他实体

        这里的n最开始是a别名,是指向a的引用,引用只能引用一个实体,一旦有了就不能再换了!所以这里的n拿到的是b的值,并不是引用了b,由于n是a的别名,二者共用一块空间,所以改了n改成了20,因此a也会是20!

        1.3常引用

        在C++中,常引用是指在函数参数列表或变量声明中使用const关键字来修饰的引用。常引用的作用是限制对被引用对象的修改。

常引用的语法格式如下:

const 数据类型 &引用名 = 被引用对象;

常引用的特点如下:

  1. 常引用只能引用常量或临时对象,不能引用非常量对象。
  2. 常引用不允许对被引用对象进行修改,即不能通过常引用修改被引用对象的值。
  3. 常引用可以接受非常量对象、常量对象和临时对象作为参数。
  4. 常引用可以提高程序的效率,因为常引用不需要创建临时变量。

 

        需要注意的是,常引用只能引用常量或临时对象,不能引用非常量对象。如果需要引用非常量对象并且不允许修改该对象的值,可以使用const修饰符来声明常量对象。

        1.4使用场景

1.做参数

        在没有引用前,我们交换两个变量的值需要使用指针来完成.

        现在可以使用引用来完成了

2.做返回值

        下面来看一段有问题的代码:

你看出问题所在了吗?程序运行的结果是什么呢?

        这里的结果是不确定的,因为Add函数返回是c的别名,也就是引用,ret接受到的就是c,此时ret就是c,第一次调用,如果函数栈帧结束后,这块空间没有被销毁,那么ret就是3,如果空间被销毁了,那么ret就是不确定的值.

        第二次函数调用Add,虽然ret没有接受,但是因为在第一次函数调用后,ret就已经是c的别名了,是指向c的引用,由于函数栈帧空间的复用性,第二次Add的调用还是在上一次的空间,此时c更改了值,那么ret也就会修改!

        但是这是不确定的,因为在不同的编译器下,函数栈帧调用后,会不会立即清空空间,所以值是不确定的,如果销毁了,那么ret引用的值就是个随机值,如果没销毁,那就是函数正常的返回值.(vs2022下不会立即空间清除)

        但是如果加上了static修饰就会不一样,因为被static修饰的变量是静态变量,是放在静态区上的,而不是栈上,并且由于static修饰的静态的变量只能被初始化一次,所以可以在一定程度上保证安全.

        1.5传值、传引用效率比较

        以值作为参数或者返回值类型,在传参和返回期间,函数不会直接传递实参或者将变量本身直接返回,而是传递实参或者返回变量的一份临时的拷贝,因此用值作为参数或者返回值类型,效
率是非常低下的,尤其是当参数或者返回值类型非常大时,效率就更低。

如图所示,你可以看出传引用的效率还是很高的!

        传值的优点是简单、直观,不会对原始数据产生任何影响。但是,传值会导致参数的副本被创建,如果参数较大,传值的效率可能会比较低。

        传引用的优点是效率高,因为不需要创建参数的副本。同时,传引用可以直接修改原始数据,对原始数据产生影响。但是,需要注意的是,如果函数内部不需要修改参数的值,传引用可能会导致意外的修改,因此需要谨慎使用。

        1.6值和引用的作为返回值类型的性能比较

        函数可以返回值或引用作为返回类型。返回值是将函数的结果复制一份返回,而返回引用是返回原始数据的引用。

通过上述代码的比较,发现传值和指针在作为传参以及返回值类型上效率相差很大。        

        返回值的优点是简单、直观,不会对原始数据产生任何影响。但是,返回值会导致结果的副本被创建,如果结果较大,返回值的效率可能会比较低。

        返回引用的优点是效率高,因为不需要创建结果的副本。同时,返回引用可以直接修改原始数据,对原始数据产生影响。但是,需要注意的是,返回引用时需要确保原始数据的生命周期足够长,否则返回的引用可能会指向无效的数据。

        1.7引用和指针的区别

        你会发现引用在很多地方好像与指针类似,这里来区分他们二者的不同.

在语法概念上引用就是一个别名,没有独立空间,和其引用实体共用同一块空间

在底层实现上实际是有空间的,因为引用是按照指针方式来实现的

通过观察汇编我们可以看出,引用的实现是与指针相同的.

        那既然如此,引用是不是就是指针呢?我们来验证一下,指针根据平台的不同,分为4~8字节,我们来看看引用的大小.

64位平台下,指针大小8字节,而引用ccc还是1个字节的大小,因为在语法概念上引用就是一个别名,没有独立空间,和其引用实体共用同一块空间,编译器是跟语法走的.

引用和指针的不同点:

  1. 引用概念上定义一个变量的别名,指针存储一个变量地址。
  2. 引用在定义时必须初始化,指针没有要求
  3. 引用在初始化时引用一个实体后,就不能再引用其他实体,而指针可以在任何时候指向任何一个同类型实体
  4. 没有NULL引用,但有NULL指针
  5. 在sizeof中含义不同:引用结果为引用类型的大小,但指针始终是地址空间所占字节个数(32位平台下占4个字节)
  6. 引用自加即引用的实体增加1,指针自加即指针向后偏移一个类型的大小
  7. 有多级指针,但是没有多级引用
  8. 访问实体方式不同,指针需要显式解引用,引用编译器自己处理
  9. 引用比指针使用起来相对更安全

本章内容已完:
        如果您喜欢这篇文章,可以点赞、评论和分享给您的同学,这将对我提供巨大的鼓励和支持。另外,我会在未来的更新中持续探讨与本文相关的内容。我会为您带来更多关于C++的编程技术问题的深入解析、应用案例和趣味玩法等。感兴趣的话给博主点个关注,获取最新的内容消息!

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

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

相关文章

数据结构---二叉树

树是一种非线性的数据结构,它是由n(n>0)个有限结点组成一个具有层次关系的集合。把它叫做树是因为它看起来像一棵倒挂的树,也就是说它是根朝上,而叶朝下的。 树形结构中,子树之间不能有交集,…

1.Vue-在独立页面实现Vue的增删改查

题记 在独立页面实现Vue的增删改查&#xff0c;以下是具体的代码&#xff0c;和操作流程。 编写index.html页面 index.html文件如下&#xff1a; <!DOCTYPE html> <html> <head><title>Vue CRUD Example</title><!--在线导入vue文件-->&l…

如何在自动化测试中使用MitmProxy获取数据返回?

背景介绍 当我们在接口或UI自动化项目中&#xff0c;常常会出现这种现象——明明是正常请求&#xff0c;却无法获取到想要的数据返回。 比如&#xff1a; 场景A&#xff1a;页面是动态数据&#xff0c;第一次进入页面获取到的数据&#xff0c;和下次进入页面获取到的数据完全…

ASEMI整流桥GBJ2510参数:拆析其关键性能特点

编辑-Z 在众多的电力电子元件中&#xff0c;GBJ2510整流桥以其高效能和可靠性赢得了工业领域的广泛认可。这款设备是在电力系统、直流电源等一系列设备中不可或缺的组件。本文将详细反析GBJ2510整流桥参数的关键性能特点&#xff0c;以帮助用户更加全面地理解和使用这种电子设…

Blender:制作一个变形动画

就是一个球逐渐地变为一个立方体 首先创建一个球和一个立方体 然后把两个物体放在一起&#xff0c;放缩球&#xff0c;让球包含立方体 之后选中球&#xff0c;为其添加修改器&#xff0c;缩裹 在这里选择缩裹对象为立方体 然后在应用下拉箭头中选择“应用为形态键” 下一步选中…

尚硅谷Flink(二)DStream API

目录 &#x1f320;不会点 &#x1fa90;DataStream API ​编辑 &#x1f320; 执行环境 创建执行环境 执行模式 触发程序执行 &#x1f320;源算子 准备基础类型 从集合中读取数据 从文件读取数据 从 Socket 读取数据 从 Kafka 读取数据 &#xff08;没学过&#xff09; …

【MATLAB-Retinex图像增强算法的去雾技术】

续&#xff1a;【MATLAB-基于直方图优化的图像去雾技术】 【MATLAB-Retinex图像增强算法的去雾技术】 1 原图2 MATLAB实现代码3 结果图示 参考书籍&#xff1a;计算机视觉与深度学习实战:以MATLAB、Python为工具&#xff0c; 主编&#xff1a;刘衍琦, 詹福宇&#xff0c; 王德建…

【ElasticSearch】使用 Java 客户端 RestClient 实现对文档的查询操作,以及对搜索结果的排序、分页、高亮处理

文章目录 前言&#xff1a;RestClient 查询文档的 RestAPI一、全文检索查询1.1 match_all 查询1.2 match 查询1.3 multi_match 查询 二、精确查询2.1 term 查询2.2 range 查询 三、复合查询&#xff1a;Boolean 查询与 function score 查询的综合案例四、对查询结果的处理4.1 将…

ArcGIS笔记5_生成栅格文件时保存报错怎么办

本文目录 前言Step 1 直接保存到指定文件夹会报错Step 2 先保存到默认位置再数据导出到指定文件夹 前言 有时生成栅格文件时&#xff0c;保存在自定义指定的文件夹内会提示出错&#xff0c;而保存到默认位置则没有问题。因此可以通过先保存到默认位置&#xff0c;再数据导出到…

【Eclipse】设置自动提示

前言&#xff1a; eclipse默认有个快捷键&#xff1a;alt /就可以弹出自动提示&#xff0c;但是这样也太麻烦啦&#xff01;每次都需要手动按这个快捷键&#xff0c;下面给大家介绍的是&#xff1a;如何设置敲的过程中就会出现自动提示的教程&#xff01; 先按路线找到需要的页…

来入门一下C语言打印Hello World

&#x1f4da;目录 安装程序官网下载软件启动程序运行代码解决乱码 安装环境&#xff08;必看&#xff09;IntelliJ Clion 环境执行运行的exe出问题了安装MinGW官网&#xff08;太慢了跳过&#xff09;Clion软件的MinGW 在这里插入图片描述 ![在这里插入图片描述](https://img-…

OpenAI开放gpt-3.5turbo微调fine-tuning测试教程

文章目录 openai微调 fine-tuning介绍openai微调地址jsonl格式数据集准备点击上传文件 openai微调 fine-tuning介绍 openai微调地址 网址&#xff1a;https://platform.openai.com/finetune jsonl格式数据集准备 使用Chinese-medical-dialogue-data数据集git clone进行下载 …

18.(开发工具篇Gitlab)Git如何回退到指定版本

首先: 使用git log命令查看提交历史,找到想要回退的版本的commit id. 使用git reset命令 第一步:git reset --hard 命令是强制回到某一个版本。执行后本地工程回退到该版本。 第二步:利用git push -f命令强制推到远程 如下所示: 优点:干净利落,回滚后完全回到最初状态…

C# 图解教程 第5版 —— 第4章 类型、存储和变量

文章目录 4.1 C# 程序是一组类型声明4.2 类型是一种模板&#xff08;*&#xff09;4.3 实例化类型4.4 数据成员和函数成员4.5 预定义类型4.6 用户定义类型4.7 堆和栈&#xff08;*&#xff09;4.8 值类型和引用类型4.9 变量4.9.1 变量声明4.9.2 多变量声明&#xff08;*&#x…

【LeetCode】每日一题两数之和寻找正序数组的中位数找出字符串中第一个匹配项的下标在排序数组中查找元素的第一个和最后一个位置

主页点击直达&#xff1a;个人主页 我的小仓库&#xff1a;代码仓库 C语言偷着笑&#xff1a;C语言专栏 数据结构挨打小记&#xff1a;初阶数据结构专栏 Linux被操作记&#xff1a;Linux专栏 LeetCode刷题掉发记&#xff1a;LeetCode刷题 算法&#xff1a;算法专栏 C头…

iCloud涨价不用慌!学会使用群晖生态将本地SSD“上云”

文章目录 前言本教程解决的问题是&#xff1a;按照本教程方法操作后&#xff0c;达到的效果是想使用群晖生态软件&#xff0c;就必须要在服务端安装群晖系统&#xff0c;具体如何安装群晖虚拟机请参考&#xff1a; 1. 安装并配置synology drive1.1 安装群辉drive套件1.2 在局域…

【node】nodemailer配置163、qq等邮件服务指南

上一章 【node】发送邮件及附件简要使用说明 邮箱配置 参数配置参考如下&#xff1a; let transporter nodemailer.createTransport({host: smtp.qq.com,port: 465,secure: true,auth: {user: **********,pass: your-password} });邮箱服务提供商的要求&#xff0c;配置SM…

Python数据挖掘:入门、进阶与实用案例分析——自动售货机销售数据分析与应用

文章目录 摘要01 案例背景02 分析目标03 分析过程04 数据预处理1. 清洗数据1.1 合并订单表并处理缺失值1.2 增加“市”属性1.3 处理订单表中的“商品详情”属性1.4 处理“总金额&#xff08;元&#xff09;”属性 2.属性选择3.属性规约 05 销售数据可视化分析1.销售额和自动售货…

Linux 文件系统逻辑结构图的解释

task_struct进程结构体&#xff0c;表示一个运行的进程。 task_struct中的fs指向fs_struct结构体。fs_struct表示这个进程支持的文件系统。 root指向根目录dentry&#xff0c;dentry中的d_inode指向改进程根目录在存储设备中的inode节点。 pwd指向当前进程所在的目录结构体den…

深入理解Java线程

1. 线程基础知识 1.1 线程和进程 进程&#xff1a;进程是代码在数据集合上的一次运行活动&#xff0c;是系统进行资源分配和调度的 基本单位。线程&#xff1a;线程是进程的一个执行路径&#xff0c;一个进程中至少有一个线程&#xff0c;进程中的多个 线程共享进程的资源 1…