你了解引用和指针的区别吗?

前言:

在计算机编程中,引用和指针是两个重要的概念,它们用于处理内存中的数据。它们在很多编程语言中都有相应的支持,例如C++和C。对于c语言来说,指针是最重要的概念之一,想要学好c语言就难以绕开对于指针的学习。那么对于c++来说,引用这一概念也同样如此。如果对指针还有不太了解的同学可以去看看我的关于指针初阶到进阶的博客,内容非常详细:

C语言内功修炼---指针详讲(初阶)-CSDN博客

C语言内功修炼--指针详讲(进阶)-CSDN博客

1.引用概念

引用是一个别名,它为一个已存在的变量提供了一个额外的名字。引用在声明时必须初始化,并且在其生命周期内始终引用相同的变量。可以理解为给某个变量起一个外号。

 引用的声明

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

int num = 42;
int &ref = num;//注意,引用必须初始化,且不能修改其引用对象
ref = 55; // 修改ref会影响num

引用类型必须和引用实体是同种类型的


2.引用的特性

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


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


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

 3.常引用

C++ 中的 "常引用"(const reference)是指在声明引用时使用了 const 修饰符,从而表明引用所指向的值不能被修改。常引用的主要作用是在函数参数传递中,以及在函数返回值中避免不必要的拷贝。

观察以下代码: 

当我们想引用一个常量时,需要加const 修饰,因为本身常量就不能被修改。这里涉及到权限大小的概念,一般认为,相同的变量用const修饰会使得该变量的权限”变小了“。而我们的编译器认为权限变小或者权限相等是安全的,权限变大是不安全的。这也是为什么我们想引用一个常量需要用const修饰。

为什么使用常引用?

1.避免拷贝: 在函数参数传递中,使用常引用可以避免不必要的对象拷贝提高程序性能。如果不使用常引用,传递大型对象时可能会导致额外的拷贝操作。

2.保护数据: 常引用可以用于声明对数据的只读访问,防止在函数内部意外修改传递的数据。

3.适用于临时对象: 常引用可以绑定到临时对象,使得在函数调用期间可以使用这些临时对象,而不需要为其创建命名变量。

 4.引用的使用场景

1.做参数

void Swap(int& left, int& right)
{
int temp = left;
left = right;
right = temp;
}

比如我们想 实现一个交换数值函数,使用引用就可以通过改变形参的值来影响实际参数,类似指针。

2.做返回值

 我们可以看到,因为n被static修饰,在静态区,生命周期是全局,所以当我们返回其引用时依旧可以访问并修改n的值。a作为返回值其实也是一个对n的引用,而对a修改实际上就是对n修改。

那如果n没有被static修饰,却被作为引用返回了呢?

思考以下代码

函数返回时,出了函数作用域,如果返回对象还在(还没还给系统,比如被static修饰或者是全局变量),则可以使用引用返回,如果已经还给系统了,则必须使用传值返回。像上述代码的变量c,出了函数作用域后该变量的空间就被系统回收了,此时ret的地址同样是被回收的变量c之前的地址,再输出ret就会出现不确定的结果。因为我们已经不知道该空间被回收之后干了什么(可能被其它变函数栈帧中的变量覆盖),所以得到的结果是不确定的。

5. 传值、传引用效率比较

以值作为参数或者返回值类型,在传参和返回期间,函数不会直接传递实参或者将变量本身直接返回,而是传递实参或者返回变量的一份临时的拷贝,因此用作为参数或者返回值类型,效率是非常低下的,尤其是当参数或者返回值类型非常大时,效率就更低。那么对于引用来说,它不需要临时拷贝,而是返回一个"别名",用做形参时,也只是一个临时的”别名“,函数生命周期结束,该别名就直接被销毁。这一点来说,引用和指针起到的作用几乎是一样的。

1.传参效率比较

测试方法:两个被测试函数只允许参数类型不一样,函数调用相同次数的情况下,分析各自所需时间大小。

2.返回值效率比较

测试方法:两个被测试函数只允许返回值类型不一样,函数调用相同次数的情况下,分析各自所需时间大小。

总结:

无论是做参数还是做返回值,传值和指针在作为传参以及返回值类型上效率相差很大

 6.引用和指针的区别

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

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

引用和指针的不同点:
1. 引用概念上是定义一个变量的别名,指针存储一个变量地址
2. 引用在定义时必须初始化,指针没有要求
3. 引用在初始化时引用一个实体后,就不能再引用其他实体,而指针可以在任何时候指向任何
一个同类型实体。

4. 没有NULL引用,但有NULL指针。
5. 在sizeof中含义不同:引用结果为引用类型的大小,但指针始终是地址空间所占字节个数(32
位平台下占4个字节)


6. 引用自加即引用的实体增加1,指针自加即指针向后偏移一个类型的大小
7. 有多级指针,但是没有多级引用
8. 访问实体方式不同,指针需要显式解引用,引用编译器自己处理
9. 引用比指针使用起来相对更安全

     引用在定义时就与变量绑定了,指针可以随意切换指向的地址空间。从某种角度来说,权限越大,越不安全。

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

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

相关文章

演讲回顾:如何为大规模研发团队加速CI构建,实现高效流水线

近日,龙智联合Atlassian举办的DevSecOps研讨会年终专场”趋势展望与实战探讨:如何打好DevOps基础、赋能创新”在上海圆满落幕。龙智Atlassian技术与顾问咨询团队,以及清晖、JamaSoftware、CloudBees等生态伙伴的嘉宾发表了主题演讲&#xff0…

vue项目开发vscode配置

配置代码片段 步骤如下: 文件->首选项->配置用户代码片段新增全局代码片段起全局代码片段文件名“xxx.code-snippets” 这里以配置vue2初始代码片段为例,配置具体代码片段 {"name": "vue-sph","version": "…

蓝桥杯备战——13.PCF8591芯片的使用

目录 1.芯片简介2.读写时序3.控制字4.代码封装库5.原理图分析6.使用示例 1.芯片简介 截取自NXP的PCF8591芯片数据手册,我把重点关注部分划出来了,请务必自行阅读一遍数据手册! 2.读写时序 ①器件地址: Bit0决定是读还是写操作&…

SQL Server数据库日志查看若已满需要清理的三种解决方案

首先查看获取实例中每个数据库日志文件大小及使用情况,根据数据库日志占用百分比来清理 DBCC SQLPERF(LOGSPACE) 第一种解决方案: 在数据库上点击右键 → 选择 属性 → 选择 文件,然后增加数据库日志文件的文件大小。 第二种解决方案 手动…

安全通信设置:使用 OpenSSL 为 Logstash 和 Filebeat 提供 SSL 证书

在为 Elasticsearch 采集数据时,我们经常使用到 Filebeat 及 Logstash。在我们之前的很多教程中,我们通常不为 Filebeat 和 Logstash 之前的通信做安全配置。 如何为 Filebeat 及 Logstash 直接建立安全的链接?这个在很多的情况下是非常有用的…

【CSS】css如何实现字体大小小于12px?

【CSS】css如何实现字体大小小于12px? 问题解决方案transform: scale(0.5)(常用)SVG 矢量图设置text 问题 文字需要显示为12px,但是小于12px的,浏览器是显示不来的 解决方案 transform: scale(0.5)(常用&#xff0…

OnlyOffice:释放无限创意,打造高效协作新体验

Onlyoffice 💖前言一、💫开发者版本介绍二、💫开发者版本特点三、💫最新版重磅来袭,8.0版本介绍1.显示协作者头像2.插件 UI 界面更新 四、✨Windows部署ONLYOFFICE1.安装Erlang2.安装RabbitMQ3.安装Redis4.安装Postgre…

归并排序

1 确定分界点 mid &#xff08;lr&#xff09;/2 2 递归排序left right 3 归并 合二为一 #include<bits/stdc.h> using namespace std; const int N1e910; int q[N],tmp[N],n;void merge_sort(int q[],int l,int r) {if(l>r)return;int midlr>>1;merge_sort(…

Datax3.0+DataX-Web部署分布式可视化ETL系统

一、DataX 简介 DataX 是阿里云 DataWorks 数据集成的开源版本&#xff0c;主要就是用于实现数据间的离线同步。DataX 致力于实现包括关系型数据库&#xff08;MySQL、Oracle 等&#xff09;、HDFS、Hive、ODPS、HBase、FTP 等各种异构数据源&#xff08;即不同的数据库&#x…

arm 汇编积累

C语言函数与汇编对应关系 一、MOV 系列指令 1、指令格式 MOV{条件}{S} 目的寄存器&#xff0c;源操作数 2、含义解析&#xff1a; &#xff08;1&#xff09;&#xff1a;mov 指令传送数据 案例&#xff1a; MOV R0,R1 ; R0 R1; MOV PC,R14 ;PC R14; MOV R0,R…

2024 RTE行业(实时互动行业)人才发展学习总结

解决方案 人才画像 开发者人才素质要求&#xff1a; 具备多个领域的技术知识注重团队合作&#xff0c;具备协作能力以用户为导向的用户体验意识具备创新思维和解决问题的能力需快速响应行业变化和持续的学习能力具备项目管理能力 学习和吸收新知识的渠道 RTE人才分类

简述MinewSemi的GNSS模块引领体育与健康科技革新

体育与健康科技领域的创新一直在推动人们更健康、更活跃的生活方式。创新微公司的GNSS模块正成为这一变革的关键推动力。本文将深入研究MinewSemi的GNSS模块在体育和健康追踪领域的创新应用&#xff0c;探讨其如何帮助个体更全面地了解和改善自己的身体状态。 1. 个性化运动轨迹…

PgSQL技术内幕 - case when表达式实现机制

PgSQL技术内幕 - case when表达式实现机制 CASE表达式如同 C语言中的if/else语句一样&#xff0c;为SQL添加了条件逻辑处理能力&#xff0c;可以根据不同条件返回不同结果。PgSQL支持两种语法&#xff1a;简单表达式和搜索表达式。 1、搜索表达式 语法如下&#xff1a; CASE WH…

蓝桥杯----凑算式

这个算式中A~I代表1~9的数字,不同的字母代表不同的数字。 比如: 68/3952/714 就是一种解法, 53/1972/486 是另一种解法. 这个算式一共有多少种解法? 注意:你提交应该是个整数,不要填写任何多余的内容或说明性文字。 代码 public class _03凑算式 {static int a[] {1,2,3…

学生信息|基于Springboot的学生信息管理系统设计与实现(源码+数据库+文档)

学生信息管理系统目录 目录 基于Springboot的学生信息管理系统设计与实现 一、前言 二、系统功能设计 三、系统实现 1、管理员登录 2、课程管理 3、公告信息管理 4、公告类型管理 四、数据库设计 1、实体ER图 2、具体的表设计如下所示&#xff1a; 五、核心代码 六、…

关于node.js奇数版本不稳定 将11.x.x升级至16.x.x不成功的一系列问题(一)

据说vue2用16稳定一些 vue3用18好一点&#xff08;但之前我vue3用的16.18.1也可以&#xff09; 为维护之前的老项目 先搞定node版本切换 下载nvm node版本管理工具 https://github.com/coreybutler/nvm-windows/releases 用这个nvm-setup.zip安装包 安之前最好先将之前的nod…

071:vue中过滤器filters的使用方法(图文示例)

第071个 查看专栏目录: VUE ------ element UI 专栏目标 在vue和element UI联合技术栈的操控下&#xff0c;本专栏提供行之有效的源代码示例和信息点介绍&#xff0c;做到灵活运用。 提供vue2的一些基本操作&#xff1a;安装、引用&#xff0c;模板使用&#xff0c;computed&a…

Linux-3进程概念(一)

1.冯诺伊曼结构 1.1 冯诺依曼结构的概念 冯诺依曼结构&#xff0c;又称为普林斯顿结构&#xff0c;是一种将程序指令存储器和数据存储器合并在一起的存储器结构。程序指令存储地址和数据存储地址指向同一个存储器的不同物理位置&#xff0c;因此程序指令和数据的宽度相同&…

CSS是一门需要单独学习的技术吗?

CSS (Cascading Style Sheets) &#xff0c;做前端开发的人都很清楚&#xff0c;因为这是他们的一项必不可少的技能。我以前也是知道CSS&#xff0c;但从来没有单独学习过&#xff0c;认为就它只是用来渲染网页的表现层效果&#xff0c;定制页面和内元素的布局、颜色和字体等&a…

JVM 性能调优 - 参数调优(3)

查看 JVM 内存的占用情况 编写代码 package com.test;public class PrintMemoryDemo {public static void main(String[] args) {// 堆内存总量long totalMemory Runtime.getRuntime().totalMemory();// jvm 试图使用的最大堆内存long maxMemory Runtime.getRuntime().maxM…