当前位置: 首页 > news >正文

C++入门:引用是什么

目录

1.引用的概念

2.引用的特征

3.常引用

4.引用使用场景

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

6.引用与指针的区别


1.引用的概念

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

语法:

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

 示例:

#include<iostream>
using namespace std;int main()
{int a = 0;int& b = a;//&符号放在 类型和变量之间时是引用 ,其他是取地址,一个符号多种用法cout << &a << endl;cout << &b << endl;//两个地址相同,a,b表示的是同一块空间a++;cout << b << endl;//b也会+1,return 0;
}

 注意:引用类型必须和引用实体同种类型的。

2.引用的特征

  1. 引用在定义时必须初始化
  2.  一个变量可以有多个引用
  3. 引用一旦引用一个实体,再不能引用其他实体

示例:

int main()
{//int& b;//1.引用在定义时必须初始化,要不然不知道是谁的别名。int a = 10;int& b = a;//2.一个变量可以有多个引用(别名)int& c = a;int& d = b;//也可以为引用取别名,都是指的同一块空间//3.C++一旦引用一个实体,再不能引用其他实体int x = 1;b = x;//这里是赋值,不是把b改成x的别名return 0;
}

3.常引用

注意:在引用过程中,权限可以平移,可以缩小,但是不能放大。

什么意思呢,我们看下面代码:const是常量限定符,被const修饰的值不能被修改

int main()
{const int a = 0;//a不能被修改//int& b = a;//1.权限放大,报错,因为b没有用const修饰,可以被修改int b = a;//简单赋值操作,可以const int& c = a;//2.权限的平移//3.权限的缩小int x = 0;const int& y = x;//x可以修改,修改后y也会改变,但不能直接修改yreturn 0;
}

临时变量: 

程序在运行时会产生临时变量,只在调用期间有效,这些临时变量具有常属性,它们的值不能被修改,以下三种情况会产生临时变量:

  1. 值传递,(函数传值,传指针,以及函数值返回)
  2. 引用时实参和形参的类型不匹配
  3. 强制类型转换

 引用时实参和形参的类型不匹配:

如果取别名时引用类型与引用实体类型不同,会发生截断,类型提升,转换时中间都会产生临时变量,然后这个引用就是临时变量的别名,因为这个临时变量具有常属性,不能修改,所以引用时也需要用const修饰,引用的是中间产生的临时变量。如果没有被const修饰,那这个引用的值可以被修改,权限放大,会报错。

int main()
{int i = 0;//double d = i;//赋值,可以//int& d = i;//可以,权限平移//double& d = i;错误,类型不同,产生临时变量,d没有被const修饰,可以被修改,权限放大const double& d = i;//正确写法return 0;
}

值传递,函数值返回:

int func()
{int a = 0;return a;
}int main()
{int ret = func();//传值返回,函数返回过程中会用临时变量保存返回的值,拷贝可以//int& ret1 = func(); //传值返回 中间生成的临时变量具有常性,不能修改,这里权限放大const int& ret1 = func();//权限平移,可以return 0;
}

4.引用使用场景

1.做参数:

#include<iostream>
using namespace std;void Swap(int& x, int& y)
{int t = x;x = y;y = t;
}int main()
{int a = 1;int b = 2;Swap(a, b);cout << "a = " << a << " b = " << b << endl;return 0;
}

2.做返回值:

如果函数返回时,出了函数作用域,如果返回对象还在(还没有还给系统),没有被销毁,如:全局变量,堆区开辟的空间以及静态变量,则可以使用引用返回,如果已经还给了系统,则必须使用传值返回

不能返回局部变量的引用,引用的这块空间可能被修改。示例:

//传引用返回,相当于返回的是n的引用
int& Count()
{int n = 0;n++;return n;
}int main()
{int& ret = Count();//这里打印的值可能是1,也可能是随机值cout << ret << endl;//X86下第一次不受影响是因为调用cout函数,先传参,取值之前还没有被覆盖。//然后ret位置的值才会被覆盖,覆盖之后ret的这块空间可能已经被修改cout << ret << endl;return 0;
}

下面代码输出什么结果?为什么

int& Add(int a, int b)
{int c = a + b;return c;
}
int main()
{int& ret = Add(1, 2);Add(3, 4);cout << "Add(1, 2) is :"<< ret <<endl;//7return 0;
}

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

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

代码:

#include <time.h>
struct A{ int a[10000]; };
void TestFunc1(A a){}
void TestFunc2(A& a){}
void TestRefAndValue()
{A a;// 以值作为函数参数size_t begin1 = clock();for (size_t i = 0; i < 10000; ++i)TestFunc1(a);size_t end1 = clock();// 以引用作为函数参数size_t begin2 = clock();for (size_t i = 0; i < 10000; ++i)TestFunc2(a);size_t end2 = clock();// 分别计算两个函数运行结束后的时间cout << "TestFunc1(A)-time:" << end1 - begin1 << endl;cout << "TestFunc2(A&)-time:" << end2 - begin2 << endl;
}

可以发现传值效率非常低,引用它需要拷贝大量的数据,传引用效率就非常高了。

6.引用与指针的区别

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

int main()
{int a = 10;int& ra = a;cout<<"&a = "<<&a<<endl;cout<<"&ra = "<<&ra<<endl;//两个地址相同return 0;
}

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

我们来看下面代码以及这段代码的汇编代码:

可以发现:指针和引用底层汇编代码是相同的,但是它们两个的语法不同。

 引用和指针的不同点:

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

本篇结束。

相关文章:

C++入门:引用是什么

目录 1.引用的概念 2.引用的特征 3.常引用 4.引用使用场景 5.传值&#xff0c;传引用效率比较 6.引用与指针的区别 1.引用的概念 引用不是新定义一个变量&#xff0c;而是给已存在变量取了一个别名&#xff0c;编译器不会为引用变量开辟内存空 间&#xff0c;它和它引用…...

2023年人工智能与自动化控制国际学术会议(AIAC 2023)

2023年人工智能与自动化控制国际学术会议&#xff08;AIAC 2023&#xff09; The 2023 International Conference on Artificial Intelligence and Automation Control 2023年人工智能与自动化控制国际学术会议&#xff08;AIAC 2023&#xff09;将于2023年10月27-29日在中…...

分布式核心知识以及常见微服务框架

分布式中的远程调用 在微服务架构中&#xff0c;通常存在多个服务之间的远程调用的需求。远程调用通常包含两个部分&#xff1a;序列化和通信协议。常见的序列化协议包括json、xml、 hession、 protobuf、thrift、text、 bytes等&#xff0c;目前主流的远程调用技术有基于HTTP…...

Unity记录4.1-存储-根据关键字加载Tile

文章首发见博客&#xff1a;https://mwhls.top/4810.html。 无图/格式错误/后续更新请见首发页。 更多更新请到mwhls.top查看 欢迎留言提问或批评建议&#xff0c;私信不回。 汇总&#xff1a;Unity 记录 摘要&#xff1a;实现完 Tilemap 地图生成后&#xff0c;实现根据关键字…...

数据结构—树表的查找

7.3树表的查找 ​ 当表插入、删除操作频繁时&#xff0c;为维护表的有序表&#xff0c;需要移动表中很多记录。 ​ 改用动态查找表——几种特殊的树 ​ 表结构在查找过程中动态生成 ​ 对于给定值key ​ 若表中存在&#xff0c;则成功返回&#xff1b; ​ 否则&#xff0…...

微信小程序测试策略和注意事项?

一、测试前准备&#xff08;环境搭建&#xff09; 1、前端页面 微信 Web 开发者工具安装、授权测试用的微信号可预览和调试小程序 2、管理后台 配置内网测试服务器环境&#xff0c;通过 PC 端 Web 站点管理小程序前端的输出内容&#xff0c;可从开发人员获取管理账号进行测…...

VUE3封装EL-ELEMENT-PLUS input组件

VUE3封装EL-ELEMENT-PLUS input组件 完整代码 <template><div><div><div class"lable_top" v-if"label"><label :class"lable_sty">{{ label }}</label></div><el-inputv-model"inputValue&…...

RISC-V公测平台发布 · 在SG2042上配置Jupiter+Octave科学计算环境

简介 JupyterHub是一个开源的共享计算平台&#xff0c;它为每个用户管理一个单独的 Jupyter 环境&#xff0c; 可以用于学生班级、企业数据科学小组或科学研究小组。它是一个多用户中心&#xff0c;可以生成、管理和代理多个单用户Jupyter笔记本服务器的实例。 GNU Octave是一…...

初识Sentinel

目录 1.解决雪崩的方式有4种&#xff1a; 1.1.2超时处理&#xff1a; 1.1.3仓壁模式 1.1.4.断路器 1.1.5.限流 1.1.6.总结 1.2.服务保护技术对比 1.3.Sentinel介绍和安装 1.3.1.初识Sentinel 1.3.2.安装Sentinel 1.4.微服务整合Sentinel 2.流量控制 2.1.簇点链路 …...

【官方中文文档】Mybatis-Spring #注入映射器

注入映射器 与其在数据访问对象&#xff08;DAO&#xff09;中手工编写使用 SqlSessionDaoSupport 或 SqlSessionTemplate 的代码&#xff0c;还不如让 Mybatis-Spring 为你创建一个线程安全的映射器&#xff0c;这样你就可以直接注入到其它的 bean 中了&#xff1a; <bea…...

UG\NX 二次开发 相切面、相邻面的选择控件

文章作者:里海 来源网站:https://blog.csdn.net/WangPaiFeiXingYuan 简介: 有群友问“UFUN多选功能过滤面不能选择相切面或相邻面之类的吗?” 这个用Block UI的"面收集器"就可以,ufun函数是不行的。 效果: C++语言在UG二次开发中的应用及综合分析 C++ …...

Quartz任务调度框架介绍和使用

一、Quartz介绍 Quartz [kwɔːts] 是OpenSymphony开源组织在Job scheduling领域又一个开源项目&#xff0c;完全由Java开发&#xff0c;可以用来执行定时任务&#xff0c;类似于java.util.Timer。但是相较于Timer&#xff0c; Quartz增加了很多功能&#xff1a; 1.持久性作业 …...

drools8尝试

drools7升级到drools8有很大很大的变更.几乎不能说是一个项目了. 或者说就是名字相同的不同项目, 初看下来变化是这样 两个最关键的东西都retired了 https://docs.drools.org/8.42.0.Final/drools-docs/drools/migration-guide/index.html business central变成了一个VS code…...

【机器学习】python基础实现线性回归

手写梯度下降的实现ykxb的线性回归 算法步骤&#xff1a; &#xff08;1&#xff09;构造数据&#xff0c;y3*x5; &#xff08;2&#xff09;随机初始化和&#xff0c;任意数值&#xff0c;例如9,10; &#xff08;3&#xff09;计算&#xff0c;,并计算 &#xff08;4&…...

vue table合并行 动态列名

需求: 1.合并行,相同数据合并 2,根据后端返回数据动态显示列名, 我这个业务需求是,每年增加一列,也就是列名不是固定的,后端返回数据每年会多一条数据,根据返回数据显示列名 实现: html <el-table v-loading"loading" :data"dataList" :span-metho…...

Spring Cloud Alibaba-Nacos Discovery--服务治理

1 服务治理介绍 先来思考一个问题 通过上一章的操作&#xff0c;我们已经可以实现微服务之间的调用。但是我们把服务提供者的网络地址 &#xff08;ip&#xff0c;端口&#xff09;等硬编码到了代码中&#xff0c;这种做法存在许多问题&#xff1a; 一旦服务提供者地址变化&am…...

【C++】unordered_map和unordered_set的使用 及 OJ练习

文章目录 前言1. unordered系列关联式容器2. map、set系列容器和unordered_map、unordered_set系列容器的区别3. unordered_map和unordered_set的使用4. set与unordered_set性能对比5. OJ练习5.1 在长度 2N 的数组中找出重复 N 次的元素思路分析AC代码 5.2 两个数组的交集思路分…...

初识 JVM 01

JVM JRE JDK的关系 JVM 的内存机构 程序计数器 java指令的执行流程&#xff1a; 1 右侧的java源代码编译为左侧的java字节码&#xff08;右侧第一个方块对应左侧第一个方块&#xff09; 2 字节码 经过解释器 变为机器码 3 机器码就可以被cpu来执行 程序计数器的作用就…...

FPGA应用学习笔记----I2S和总结

时序一致在慢时序方便得多 增加了时序分布和分析的复杂性 使用fifo会开销大量资源...

归并排序之从微观看递归

前言 这次&#xff0c;并不是具体讨论归并排序算法&#xff0c;而是利用归并排序算法&#xff0c;探讨一下递归。归并排序的特点在于连续使用了两次递归调用&#xff0c;这次我们将从微观上观察递归全过程&#xff0c;从本质上理解递归&#xff0c;如果能看完&#xff0c;你一…...

云原生核心技术 (7/12): K8s 核心概念白话解读(上):Pod 和 Deployment 究竟是什么?

大家好&#xff0c;欢迎来到《云原生核心技术》系列的第七篇&#xff01; 在上一篇&#xff0c;我们成功地使用 Minikube 或 kind 在自己的电脑上搭建起了一个迷你但功能完备的 Kubernetes 集群。现在&#xff0c;我们就像一个拥有了一块崭新数字土地的农场主&#xff0c;是时…...

css实现圆环展示百分比,根据值动态展示所占比例

代码如下 <view class""><view class"circle-chart"><view v-if"!!num" class"pie-item" :style"{background: conic-gradient(var(--one-color) 0%,#E9E6F1 ${num}%),}"></view><view v-else …...

DeepSeek 赋能智慧能源:微电网优化调度的智能革新路径

目录 一、智慧能源微电网优化调度概述1.1 智慧能源微电网概念1.2 优化调度的重要性1.3 目前面临的挑战 二、DeepSeek 技术探秘2.1 DeepSeek 技术原理2.2 DeepSeek 独特优势2.3 DeepSeek 在 AI 领域地位 三、DeepSeek 在微电网优化调度中的应用剖析3.1 数据处理与分析3.2 预测与…...

Docker 运行 Kafka 带 SASL 认证教程

Docker 运行 Kafka 带 SASL 认证教程 Docker 运行 Kafka 带 SASL 认证教程一、说明二、环境准备三、编写 Docker Compose 和 jaas文件docker-compose.yml代码说明&#xff1a;server_jaas.conf 四、启动服务五、验证服务六、连接kafka服务七、总结 Docker 运行 Kafka 带 SASL 认…...

Nuxt.js 中的路由配置详解

Nuxt.js 通过其内置的路由系统简化了应用的路由配置&#xff0c;使得开发者可以轻松地管理页面导航和 URL 结构。路由配置主要涉及页面组件的组织、动态路由的设置以及路由元信息的配置。 自动路由生成 Nuxt.js 会根据 pages 目录下的文件结构自动生成路由配置。每个文件都会对…...

Psychopy音频的使用

Psychopy音频的使用 本文主要解决以下问题&#xff1a; 指定音频引擎与设备&#xff1b;播放音频文件 本文所使用的环境&#xff1a; Python3.10 numpy2.2.6 psychopy2025.1.1 psychtoolbox3.0.19.14 一、音频配置 Psychopy文档链接为Sound - for audio playback — Psy…...

CRMEB 框架中 PHP 上传扩展开发:涵盖本地上传及阿里云 OSS、腾讯云 COS、七牛云

目前已有本地上传、阿里云OSS上传、腾讯云COS上传、七牛云上传扩展 扩展入口文件 文件目录 crmeb\services\upload\Upload.php namespace crmeb\services\upload;use crmeb\basic\BaseManager; use think\facade\Config;/*** Class Upload* package crmeb\services\upload* …...

【学习笔记】深入理解Java虚拟机学习笔记——第4章 虚拟机性能监控,故障处理工具

第2章 虚拟机性能监控&#xff0c;故障处理工具 4.1 概述 略 4.2 基础故障处理工具 4.2.1 jps:虚拟机进程状况工具 命令&#xff1a;jps [options] [hostid] 功能&#xff1a;本地虚拟机进程显示进程ID&#xff08;与ps相同&#xff09;&#xff0c;可同时显示主类&#x…...

【数据分析】R版IntelliGenes用于生物标志物发现的可解释机器学习

禁止商业或二改转载&#xff0c;仅供自学使用&#xff0c;侵权必究&#xff0c;如需截取部分内容请后台联系作者! 文章目录 介绍流程步骤1. 输入数据2. 特征选择3. 模型训练4. I-Genes 评分计算5. 输出结果 IntelliGenesR 安装包1. 特征选择2. 模型训练和评估3. I-Genes 评分计…...

使用Spring AI和MCP协议构建图片搜索服务

目录 使用Spring AI和MCP协议构建图片搜索服务 引言 技术栈概览 项目架构设计 架构图 服务端开发 1. 创建Spring Boot项目 2. 实现图片搜索工具 3. 配置传输模式 Stdio模式&#xff08;本地调用&#xff09; SSE模式&#xff08;远程调用&#xff09; 4. 注册工具提…...