【C++】初阶 --- 引用(超级详细版!!!)(一)

简介: 【C++】初阶 --- 引用(超级详细版!!!)(一)

a2b5d9e83f974e918e4186cf872658b3.jpg


🍪一、引用的概念

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

比如:李逵,在家称为"铁牛",江湖上人称"黑旋风"

比如:抓 “周树人” 和我 "鲁迅"有什么关系🤭,本质上其实是一个人


🚩引用的操作符: &

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

🌰举个栗子演示👇

int main()
{
  int a = 0;
  int& b = a; //引用
  cout << &a << endl;
  cout << &b << endl;
  return 0;
}

☝️代码段中相当于给变量a取了一个别名b,通过标识名b可以在其被定义的作用域中访问变量a,可以看到地址是一样的,说明a和b共用同一块内存空间

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

🍪二、引用的特性

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

🥰请看代码与注释👇

void TestRef()
{
  int a = 10;
  // int& ra;  // 该条语句编译时会出错
  int& ra = a;
  cout << a << "  " << &a << endl;
  cout << ra << "  " << &ra << endl;
}
int main()
{
  TestRef();
  return 0;
}

🚨int& ra; 该条语句编译时会出错,是不可以的,必须要进行初始化

🍿2、一个变量可以有多个引用

🚩一个变量可以有多个引用,并且引用可以嵌套定义

🥰请看代码与注释👇

void TestRef()
{
  int a = 10;
  // int& ra;  // 该条语句编译时会出错
  int& ra = a; // ra是a的引用
  int& rra = a; // rra是a的引用
  int& rrra = ra; // rrra是ra的引用
  cout << a << "  " << &a << endl;
  cout << ra << "  " << &ra << endl; 
  cout << rra << "  " << &rra << endl;
  cout << rrra << "  " << &rrra << endl;
}
int main()
{
  TestRef();
  return 0;
}

基于引用这种可以嵌套定义并且无需多次解引用就可以直接访问被引用变量的这种特性,很多时候使用引用可以避免多级指针的出现

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

🌰举个栗子演示👇

void TestRef()
{
  int a = 10;
  int b = 20;
  int& x = a; 
  int& x = b; 
  cout << a << "  " << &a << endl;
  cout << x << "  " << &x << endl; 
  cout << b << "  " << &b << endl;
  cout << x << "  " << &x << endl;
}

由于这个特性,引用无法完全代替指针(比如链表中结构体的next指针无法用引用来代替,因为引用一旦引用一个实体,再不能引用其他实体),灵活性也不如指针,但是引用也因此比指针更安全,这也是引用这个语法的设计初衷之一(使用指针很容易出现野指针,非法访问内存空间的情况)

🍪三、常引用(被const 修饰的引用)

🚨在引用的过程中,权限可以平移,权限可以缩小,但是权限不能放大!

🍿1、权限的放大

假如a是鲁智深 可以喝酒 可以吃肉 不能杀人

给a取个别名b 叫花和尚 可以喝酒 可以吃肉 可以杀人?

a(鲁智深)和 b(花和尚)是同一个人,当然不可以杀人

🌰举个栗子👇

int main()
{
  //权限的放大
  const int a = 0;
  int& b = a;
  return 0;
}

🍿2、权限的平移

🌰举个栗子👇

int main()
{
  //权限的平移
  const int a = 0;
  const int& b = a;
  return 0;
}

🍿3、权限的缩小

🌰举个栗子👇

int main()
{
  //权限的缩小
  int a = 0; //a可以修改,可以影响b
  const int& b = a;
  return 0;
}

a可以修改,可以影响b

🍿4、临时变量具有常性

🌰举个栗子👇

int main()
{
  int i = 0;
  double& d = i;//临时变量具有常性
  return 0;
}

✅正确操作👇

int main()
{
  int i = 0;
  const double& d = i;
  return 0;
}

🚩这里涉及一个知识点:

代码段中b去引用i,i会发生隐式类型转换,i转换的结果会存入一个临时空间中。
(当赋值等号右边有运算表达式或有变量发生类型转换时,表达式或类型转换的结果都会先存入一个临时空间后再赋值给等号左边的变量)

因此这里的d引用的实质上是一块临时空间:

目录
相关文章
|
机器学习/深度学习 算法 API
XGBoost模型部署与在线预测的完整指南
XGBoost模型部署与在线预测的完整指南
1705 6
|
分布式计算 Hadoop 大数据
一口气说完MR、Storm、Spark、SparkStreaming和Flink
一口气说完MR、Storm、Spark、SparkStreaming和Flink
|
11月前
|
Android开发
Android面试之Activity启动流程简述
Android面试之Activity启动流程简述
207 6
|
10月前
|
存储 云安全 安全
带你读《阿里云安全白皮书》(二十一)——云上安全重要支柱(15)
阿里云安全白皮书(2024版)详细介绍了其在面对线上威胁时的快速响应与恢复能力。通过一体化的安全运营能力,阿里云帮助客户在极端威胁下快速感知、响应风险并恢复数据及服务。白皮书还涵盖了全面的资产梳理、及时的威胁情报分析、高效的风险识别与治理、专业的安全服务等内容,旨在为企业提供全方位的安全保障。
|
存储
外部排序快速入门详解:基本原理,败者树,置换-选择排序,最佳归并树
外部排序用于处理无法一次性加载到内存中的大规模数据排序问题。其基本原理是将外存数据划分为若干已内部排序的小块,利用内存中的缓冲区进行多路归并排序,并逐步合并以生成更大的有序块。通过增加缓冲区数量、优化关键字比较次数(如使用败者树)和调整归并段长度等方法可进一步提高排序效率。最佳归并树的应用则能有效减少磁盘I/O次数,从而优化整个排序过程。
497 8
|
人工智能 固态存储 调度
【Paper Reading】结合 NanoFlow 研究,优化大语言模型服务效率的探索
本文将深入探讨 NanoFlow 的关键思路和核心技术,分析 NanoFlow 与 阿里云人工智能平台 PAI 在实际工作中应用的潜力。
|
11月前
|
存储 人工智能 大数据
【一图看懂】云存储“4任意+3智能”升级,以数据驱动AI创新
阿里云围绕Storage for AI与AI in Storage两大领域,对其存储服务进行全面升级。
|
Java Spring
如何通过IDEA查看注解逻辑实现
如何通过IDEA查看注解逻辑实现
1219 0
|
IDE Java Shell
如何快速搭建一个 Spring Boot 项目?
本指南介绍如何通过Spring Initializr创建一个基本的Spring Boot Web项目。首先访问`start.spring.io`,选择Maven项目、Java语言、Spring Boot版本3.1.0、Java 17,并勾选Spring Web依赖。点击“Generate”下载项目模板。解压后,IDE打开项目并修改`DemoApplication.java`,添加REST控制器以实现一个简单的“Hello World!”服务。通过`@RestController`和`@GetMapping`注解定义Web端点,使用`@RequestParam`获取URL参数。
492 1