初始C++(三):引用
文章目录
- 一.引用的概念
- 二.引用的使用
- 1.引用作为输出型参数
- 2. 引用作为函数返回值
- 3.const引用
- 三.引用的一些小问题
- 四.引用和指针
- 五.引用和指针的区别
一.引用的概念
引用的作用是给一个已经存在的变量取别名,编译器不会为引用变量开空间,引用变量和被他引用的变量共用一块空间。
二.引用的使用
//类型& 引用变量名(对象名) = 引用实体;
int i = 10;
int& j = i;//j就是i的引用,也可以说j就是i的别名
上面的i和j公用一块空间:
完全可以认为i,j代表的是一个东西。比如对i++使i变成11的时候,j也会变成11:
1.引用作为输出型参数
在我们学C语言的时候,应该遇到过交换函数,就是要求写一个函数来交换两个变量的值,当时是这样写的:
void Swap(int* i, int* j)
{int tmp = *i;*i = *j;*j = tmp;
}
因为函数的形参是实参的一份临时拷贝,也就是说形参的改变不会影响到实参的变化,所以这里我们要传递需要改变的两个变量的地址,这样在Swap函数里解引用才能找到需要改变的两个变量的值。
但是每次使用都要传地址,这样显得就非常麻烦,于是C++里的引用在这里就派上了大用场,现在这个交换函数可以这样写:
void Swap1(int& i, int& j)
{int tmp = i;i = j;j = tmp;
}
int main()
{Swap1(10,20);return 0;
}
这里的形参i,j不是实参的临时拷贝了,而是两个实参的别名,对两个别名的交换就可以认为是对实参两个变量的交换。
2. 引用作为函数返回值
首先看这样的一段代码:
int f()
{int n = 0;n++;return n;
}int main()
{int ret = f();return 0;
}
来了解一下n这个值是怎么传给ret的:
1.在f()这个函数运行完之前变量n的值首先会拷贝到一个临时变量中。
2.然后f()函数结束,这个函数的空间被销毁
3.最后临时变量的值赋值给变量ret.
小知识点:临时变量
如果需要拷贝的值很小,临时变量可以是用寄存器来代替,如果很大,比如像一个结构体,那这个临时变量是在f()的上层函数中直接帮你开辟好的,这个上层函数可以认为是调用f()函数的函数,临时变量具有常性,可以理解为被const修饰了一样。
在函数值返回,隐式/显式类型转换的时候都会产生临时变量
int a = 10;
cout << (double)a << endl;//这里是显式转换
double b = a;//这里是隐式转换
接下来在看一段代码:
int f1()
{static int n = 0;n++;return n;
}int main()
{int ret = f1();return 0;
}
虽然这里的n变成了静态的变量,储存在静态区,f()函数销毁后n不会被销毁,但是计算机仍然会将n拷贝到一个临时变量中,然后再由这个临时变量返回给ret.
这里的变量n完全可以不用进行拷贝,所以上面的代码可以进行一些优化:
int& f1()//将值返回变成引用返回
{static int n = 0;n++;return n;
}int main()
{int ret = f1();return 0;
}
如果将值返回变为引用返回,返回的值将不再是临时变量,而是n的引用,也可以说返回的就是n这个变量。这样就可以减少中间拷贝的过程。
所以在返回的变量在函数销毁的时仍然存在的情况下,返回值就可以用引用返回。
明白了这一点,还可以写这样的一种代码:
//定义一个数组结构体
typedef struct Array
{int a[10];
}Array;//定义一个函数用来寻找数组中第i个位置上的值
int& at(Array& ay, int i)
{assert(i < 10);return ay.a[i]; //形参用引用来接收,ay.a[i]中的ay是main函数中定义的那个数组的别名//返回值用引用,返回的就是main函数中定义的那个数组的别名
}int main()
{Array ay; //定义一个结构体for (int i = 0; i < 10; i++){//既然返回值就是自己定义的结构体里的数组,//所以对其赋值也是完全可以at(ay, i) = i;}for (int i = 0; i < 10; i++){cout << at(ay, i) << ' ';}cout << endl;return 0;
}
通过这段代码,引用返回不但可以减少拷贝,还可以对返回值进行修改。这里的at函数返回的就是数组里第i个元素,at(ay, i) = i就可以认为对第i个元素进行赋值。
3.const引用
先说结论:指针/引用在初始化和赋值的时候只能权限保持和权限缩小,不能权限放大。
权限放大:
int main()
{const int a = 10;int& b = a;return 0;
}
变量a的类型是const int说明它具有常属性,也就是不能被改变,但是a的别名b的类型是int反而可以改变了,这就是所谓的权限放大。如果这样写代码,编译器会报错的。
权限保持/权限缩小:
int main()
{//权限保持const int a = 10;const int& b = a;//权限缩小int x = 10;const int& y = x;return 0;
}
权限保持和缩小是没问题的。指针在这一块和引用是一样的,这里就不再复述了。
三.引用的一些小问题
- 引用类型必须和引用实体是同种类型的
- 引用在定义时必须初始化
- 一个变量可以有多个引用
- 引用一旦引用一个实体,再不能引用其他实体
四.引用和指针
在语法概念这个层次上引用是不开空间的,而指针是需要开空间的。接下来通过代码的汇编指令,看看引用和指针有没有区别:
int main()
{int a = 10;int* pa = &a;*pa = 20;int& ra = a;ra = 20;return 0;
}
虽然你可能不动这些指令是什么,但你只要看指针和引用有没有区别就行。
不难发现,引用和指针在底层的指令是一模一样的。所以说,虽然表面上引用和指针是两码事,但在底层,引用其实就是指针。
五.引用和指针的区别
- 引用概念上定义一个变量的别名,指针存储一个变量地址。
- 引用在定义时必须初始化,指针没有要求
- 引用在初始化时引用一个实体后,就不能再引用其他实体,而指针可以在任何时候指向任何一个同类型实体
- 没有NULL引用,但有NULL指针
- 在sizeof中含义不同:引用结果为引用类型的大小,但指针始终是地址空间所占字节个数(32位平台下占4个字节,64位平台下占8个字节)
- 引用自加即引用的实体增加1,指针自加即指针向后偏移一个类型的大小
- 有多级指针,但是没有多级引用
- 访问实体方式不同,指针需要显式解引用,引用编译器自己处理
- 引用比指针使用起来相对更安全
相关文章:

初始C++(三):引用
文章目录一.引用的概念二.引用的使用1.引用作为输出型参数2. 引用作为函数返回值3.const引用三.引用的一些小问题四.引用和指针五.引用和指针的区别一.引用的概念 引用的作用是给一个已经存在的变量取别名,编译器不会为引用变量开空间,引用变量和被他引…...

【前端】参考C站动态发红包界面,高度还原布局和交互
最近有些小伙伴咨询博主说前端布局好难,其实都是熟能生巧! 模仿C站动态发红包界面,cssdiv实现布局,纯javascript实现交互效果 目录 1、界面效果 2、界面分析 2.1、整体结构 2.2、标题 2.3、表单 2.4、按钮 3、代码实现 3.…...

VR全景带你浪漫“狂飙”情人节,见证甜蜜心动
当情人节遇上VR,足以让情侣过一个难忘的情人节。马上情人节就要到了,大家是不是还在绞尽脑汁的想着,如何和另一半过一个浪漫的情人节呢?老套的剧情已经不能吸引人了,让我们看看VR全景给情人节带来了哪些不同的体验吧&a…...

Linux系统安全之iptables防火墙
目录 一.iptables防火墙基本介绍 二.iptables的四表五链 三.iptables的配置 1.iptables的安装 2.iptables防火墙的配置方法 四.添加、查看、删除规则 1.查看(fliter)表中的所有链 iptables -L 2.使用数字形式(fliter)表所有链 查看输出结果 iptables -nL 3.清空表中所…...
【C#基础】C# 变量与常量的使用
序号系列文章1【C#基础】C# 程序通用结构2【C#基础】C# 基础语法解析3【C#基础】C# 数据类型总结文章目录前言一. 变量(variable)1,变量定义及初始化2,变量的类别3,接收输出变量二. 常量(constantÿ…...

[ 常用工具篇 ] CobaltStrike(CS神器)基础(一) -- 安装及设置监听器详解
🍬 博主介绍 👨🎓 博主介绍:大家好,我是 _PowerShell ,很高兴认识大家~ ✨主攻领域:【渗透领域】【数据通信】 【通讯安全】 【web安全】【面试分析】 🎉点赞➕评论➕收藏 养成习…...

Redis集群
Redis集群 本章是基于CentOS7下的Redis集群教程,包括: 单机安装RedisRedis主从Redis分片集群 1.单机安装Redis 首先需要安装Redis所需要的依赖: yum install -y gcc tcl然后将课前资料提供的Redis安装包上传到虚拟机的任意目录ÿ…...

00---C++入门
1. C关键字(C98) C总计63个关键字,C语言32个关键字 2. 命名空间 在C/C中,变量、函数和后面要学到的类都是大量存在的,这些变量、函数和类的名称将都存在于全局作用域中,可能会导致很多冲突。使用命名空间的目的是对标识符的名称进…...

Spring-事务2
文章目录前言一、事务的特性(ACID)二、事务的隔离级别三、spring中的事务平台事务管理器.事务定义ISOLation_XXX:**事务隔离级别.**PROPAGATION_XXX:**事务的传播行为**.事务状态关系:四、使用XML文件配置事务1、 搭建…...

Windows Git Bash 配置
Windows Git Bash 配置 本文参考的文章: 在 Windows 的 Git Bash 中使用包管理器 - iris (ginshio.org)Git bash 安装 pacman & Windows 解压 zst 文件 | 伪斜杠青年 (lckiss.com) 一、Git的安装 Git 的安装应该是都会的,但还是应该说以下&#…...
java代码整合kettle9.3实现读取表中的数据,生成excel文件
java代码整合kettle9.3实现读取表中的数据,生成excel文件 1.简介 本次使用java代码整合kettle9.3版本,数据库使用mysql。 2.jar包导入 项目需要依赖部分kettle中的jar包,请将这部分jar包自行导入maven仓库。 <dependency><groupId…...

分享微信点餐小程序搭建步骤_微信点餐功能怎么做
线下餐饮实体店都开始摸索发展网上订餐服务。最多人选择的是入驻外卖平台,但抽成高,推广还要另买流量等问题,也让不少商家入不敷出。在这种情况下,建立自己的微信订餐小程序,做自己的私域流量是另一种捷径。那么&#…...

4、数组、切片、map、channel
目录一、数组二、切片三、map四、channel五、引用类型一、数组 数组: 数组是块连续的内存空间,在声明的时候必须指定长度,且长度不能改变所以数组在声明的时候就可以把内存空间分配好,并赋上默认值,即完成了初始化数组…...
270 uuid
270 uuid 用途 For the creation of RFC4122 UUIDs 可靠性 10000 星星 适应于浏览器或者服务器 官网链接 https://www.npmjs.com/package/uuid https://github.com/uuidjs/uuid 基本使用 import { v4 as uuidv4 } from uuid; uuidv4(); // ⇨ 9b1deb4d-3b7d-4bad-9bdd-2b0d7b3d…...

2023最新简历模板免费下载
下面分享5个简历模板网站,免费下载,建议收藏! 2023用最漂亮的简历模板,让面试官眼前一亮。 1、菜鸟图库 个人简历模板|WORD文档模板免费下载 - 菜鸟图库 菜鸟图库除了有超多设计类素材之外,还有很多办公类素材&#…...

【CSS】元素居中总结-水平居中、垂直居中、水平垂直居中
【CSS】元素居中一、 水平居中1.行内元素水平居中(1)text-align2.块级元素水平居中2.1 margin(1)margin2.2布局(1)flex justify-content(推荐)(2) flexmargin…...
spring实现AOP
文章目录前言一、AOP的底层实现原理二、AOP的两种开发模式1.使用xml配置文件1.1 添加AOP依赖1.2 创建UserService1.3创建UserServiceImpl1.4创建通知类1.5 创建applicationContext.xml(添加aop约束)1.6 测试2.使用注解开发2.1 创建bean.xml文件配置注解方…...
neovim搭建cpp环境
文章目录Windowns下NeoVim搭建cpp环境NeoVim安装插件vim-plugindentLinevim-airlinectagstagbarcoc.vimWindowns下NeoVim搭建cpp环境 在开发过程中习惯在DIE环境中使用vim作为编辑器,在单独的编辑器也常使用gvim图形化编辑器。最近看到NeoVim的特性及兼容性方面不输…...
SpringBoot AES加密 PKCS7Padding 模式
AES 简介:DES 全称为Data Encryption Standard,即数据加密标准,是一种使用密钥加密的块算法,1977年被美国联邦政府的国家标准局确定为联邦资料处理标准(FIPS) AES 密码学中的高级加密标准(Advan…...

按键输入驱动
目录 一、硬件原理 二、添加设备树 1、创建pinctrl 2、创建节点 3、检查 编译复制 三、修改工程模板编辑 四、驱动编写 1、添加keyio函数 2、添加调用 3、驱动出口函数添加释放 4、添加原子操作 5、添加两个宏定义 6、初始化原始变量 7、打开操作 8、读操作 总体代…...

[10-3]软件I2C读写MPU6050 江协科技学习笔记(16个知识点)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16...

CocosCreator 之 JavaScript/TypeScript和Java的相互交互
引擎版本: 3.8.1 语言: JavaScript/TypeScript、C、Java 环境:Window 参考:Java原生反射机制 您好,我是鹤九日! 回顾 在上篇文章中:CocosCreator Android项目接入UnityAds 广告SDK。 我们简单讲…...
【服务器压力测试】本地PC电脑作为服务器运行时出现卡顿和资源紧张(Windows/Linux)
要让本地PC电脑作为服务器运行时出现卡顿和资源紧张的情况,可以通过以下几种方式模拟或触发: 1. 增加CPU负载 运行大量计算密集型任务,例如: 使用多线程循环执行复杂计算(如数学运算、加密解密等)。运行图…...
Python如何给视频添加音频和字幕
在Python中,给视频添加音频和字幕可以使用电影文件处理库MoviePy和字幕处理库Subtitles。下面将详细介绍如何使用这些库来实现视频的音频和字幕添加,包括必要的代码示例和详细解释。 环境准备 在开始之前,需要安装以下Python库:…...
OpenLayers 分屏对比(地图联动)
注:当前使用的是 ol 5.3.0 版本,天地图使用的key请到天地图官网申请,并替换为自己的key 地图分屏对比在WebGIS开发中是很常见的功能,和卷帘图层不一样的是,分屏对比是在各个地图中添加相同或者不同的图层进行对比查看。…...

Reasoning over Uncertain Text by Generative Large Language Models
https://ojs.aaai.org/index.php/AAAI/article/view/34674/36829https://ojs.aaai.org/index.php/AAAI/article/view/34674/36829 1. 概述 文本中的不确定性在许多语境中传达,从日常对话到特定领域的文档(例如医学文档)(Heritage 2013;Landmark、Gulbrandsen 和 Svenevei…...
【无标题】路径问题的革命性重构:基于二维拓扑收缩色动力学模型的零点隧穿理论
路径问题的革命性重构:基于二维拓扑收缩色动力学模型的零点隧穿理论 一、传统路径模型的根本缺陷 在经典正方形路径问题中(图1): mermaid graph LR A((A)) --- B((B)) B --- C((C)) C --- D((D)) D --- A A -.- C[无直接路径] B -…...

【Linux】Linux 系统默认的目录及作用说明
博主介绍:✌全网粉丝23W,CSDN博客专家、Java领域优质创作者,掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域✌ 技术范围:SpringBoot、SpringCloud、Vue、SSM、HTML、Nodejs、Python、MySQL、PostgreSQL、大数据、物…...
python爬虫——气象数据爬取
一、导入库与全局配置 python 运行 import json import datetime import time import requests from sqlalchemy import create_engine import csv import pandas as pd作用: 引入数据解析、网络请求、时间处理、数据库操作等所需库。requests:发送 …...

mac:大模型系列测试
0 MAC 前几天经过学生优惠以及国补17K入手了mac studio,然后这两天亲自测试其模型行运用能力如何,是否支持微调、推理速度等能力。下面进入正文。 1 mac 与 unsloth 按照下面的进行安装以及测试,是可以跑通文章里面的代码。训练速度也是很快的。 注意…...