学习导航

  • 一、引用的基本介绍
  • 二、引用的基本特性
  • 三、引用的基本原则
    • ①引用类型和引用实体类型相同
    • ②引用类型和引用实体类型不同
  • 四、引用的基础应用
    • ①对标传址操作
    • ②作为返回值

一、引用的基本介绍

 什么是引用?通俗的讲,引用就是"取别名",我们看下面的例子:

 可以看到,引用并不会开辟新的空间。


二、引用的基本特性

特性①:必须有初始化

特性②:一个变量可以有多个引用

可以给别名取别名,但本质上都是对a的引用
特性③:一旦引用了一个实体,就不能引用其他实体

可以看到,之后b不会再引用实体c,只能对b做赋值修改


三、引用的基本原则

①引用类型和引用实体类型相同

 引用的一个极其重要的基本原则是:对变量实体的读写权限只能缩小不能放大。我们在接下来的例子中来说明这个原则。
 引用可以引用常量吗?答案是可以的。但是我们需要加上const来保证读写权限没有被放大:

✪代码分析
 我们来分析这段代码我们需要注意到,引用就是给实体取的别名,二者在地址上是一样的,对别名的修改也会改变实体的值,所以我们在取别名的时候就要保证对引用的读写权限没有扩大。就像上面的例子,10是一个只读变量,如果不加上const,那么就意味着可以通过a来修改常变量10,这显示是不行的。

②引用类型和引用实体类型不同

 引用类型必须和引用实体是同种类型吗?不一定!怎么理解这个问题呢?我们可以类比我们在C语言中学到的隐式类型转化,我们来分析中间的过程:

int main()
{double d = 6.66;int a = d;
}

 为什么可以将类型为double的变量赋值给类型为int的变量呢?实际上这个赋值过程不是一步到位的,而是存在一个 “中间变量”。这个中间变量接收d的整数部分,最后再把这个中间变量拷贝给a。需要注意的是,这个中间变量具有常属性。引用也是同样的道理:

✪代码分析
 a并不是直接引用d,而是引用这个中间变量。由于中间变量具有常属性,所以前面必须加上const修饰避免扩大读写权限。

 通过取地址我们可以确认a没有引用d,从而也间接说明了中间临时变量的存在。


四、引用的基础应用

①对标传址操作

void swap(int& a, int& b)
{int tmp = a;a = b;b = tmp;
}int main()
{int a = 10;int b = 20;swap(a, b);return 0;
}

 正是由于引用和引用实体存在互相改变的关系,所以我们可以用引用来替代传值操作。拿我们C语言中常写的swap函数举例,这样写起来是不是更爽了呢?
 但如果设计的函数中需要传入常数,那么就必须在参数前面加上const,否则存在扩大实体读写权限的风险。经过实际测试,引用的效率和传址的效率是差不多的。
 相应的,一些输出型参数也可以用引用来实现,例如:

int* sortArray(int* nums, int numsSize, int* returnSize){}

 returnSize是我们的输出型参数,在C语言中我们只能通过传址的方式实现,现在用引用也可以实现这样的效果。

②作为返回值

int& count()
{static int n = 0;n++;return n;
}

 用引用作为返回值和传统的方式相比有什么好处呢?我们先来谈谈传统的方式是如何传递返回值的:

  • 首先将预备返回的值存储到临时变量,再将临时变量拷贝给用于接收函数返回值的变量
  • 预备返回的变量小则用寄存器存储,变量大则则创建函数栈帧的时候预先为返回值创建存储空间

 如果我们使用引用,那我们根本就不需要额外的临时空间和额外的拷贝,因为我们是通过引用直接对实体进行操作的,这可以提供程序的效率。

 但是引用作为返回值只适合返回值出作用域不销毁的情况,如上面static修饰的n变量,如果我们我们引用的变量出函数作用域销毁,那我们实际上通过引用创建了间接的“野指针”

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): " << ret << endl;cout << "Add(1, 2): " << ret << endl;return 0;
}

 ret的值可能是随机值也可能不是,取决于这块空间有没有被重新覆盖和使用。cout函数栈帧的创建覆盖了Add函数的函数栈帧,所以ret的值变成随机值了

再来看几个变式:
int& Add(int a, int b)
{static int c;c = a + b;return c;
}int main()
{int& ret = Add(1, 2);Add(3, 4);cout << "Add(1, 2): " << ret << endl;cout << "Add(1, 2): " << ret << endl;return 0;
}

 变量c用static修饰后,这块空间出函数作用域后不会被销毁,不用担心被其他函数栈帧所覆盖

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

注意static语句只在初始化时执行一次

【引用】引用的概念与基本使用原则相关推荐

  1. 2020-09-22C++学习笔记之引用1(1.引用(普通引用)2.引用做函数参数 3.引用的意义 4.引用本质5.引用结论 6.函数返回值是引用(引用当左值)7测试代码)

    2020-09-22C++学习笔记之引用1(1.引用(普通引用)2.引用做函数参数 3.引用的意义 4.引用本质5.引用结论 6.函数返回值是引用(引用当左值)7测试代码) 1.引用(普通引用) 变量 ...

  2. 【C++ 语言】引用 ( 引用简介 | 指针常量 | 常量指针 | 常引用 | 引用参数 | 引用 指针 对比 )

    文章目录 I . 引用概念 II . 引用声明 III . 引用 地址 内存 分析 IV . 常引用 V . 引用作为参数 VI . 引用 与 指针 对比 I . 引用概念 C++ 对 C 扩充 : ...

  3. 引用和指针概念及区别

    一.引用和指针 指针:指针是一个特殊的变量,它里面存储的的数值为内存里的一个地址,通过*访问内存地址所指向的值 引用:引用不是新定义一个变量,而是给已存在变量取了一个别名,编译器不会为引用变量开辟内存 ...

  4. 2-5:C++快速入门之引用,引用和指针的区别

    文章目录 (1)引用的概念 (2)引用的特点 (3)常引用 (4)引用的应用场景 A:做参数 B:做返回值 (5)引用和指针 在第一次学习C语言指针时,许多教材上都会给出一个交换两个变量值的例子,开始 ...

  5. 【Android 内存优化】Bitmap 内存缓存 ( Bitmap 内存复用 | 弱引用 | 引用队列 | 针对不同 Android 版本开发不同的 Bitmap 复用策略 | 工具类代码 )

    文章目录 一.Bitmap 复用池 二.弱引用 Bitmap 内存释放 三.从 Bitmap 复用池中获取对应可以被复用的 Bitmap 对象 1.Android 2.3.3(API 级别 10)及以 ...

  6. C 语言结构体引用,引用 C 语言结构体学习

    引用 C 语言结构体学习 这篇文章很基础,是个学习的好资料,所以收藏了: 1.直接声明结构体变量: struct{ int length; int width; }box1; 这样就声明了一个名为bo ...

  7. java 引用 引用的对象,Java 引用类型简述

    强引用 ( Strong Reference ) 强引用是使用最普遍的引用.如果一个对象具有强引用,那垃圾回收器绝不会回收它.当内存空间不足,Java虚拟机宁愿抛出OutOfMemoryError错误 ...

  8. 字体设计的概念、意义与原则

    字体设计的概念 文字是一个极其庞大的体系,蕴含着人类集体的智慧,而且对人类社会文明起到了见证作用,西方的文明孕育出拉丁字母,东方的文明诞生了中国汉字. 在字体设计中,首先是将字体定位,对收集到的相关资 ...

  9. 引用 引用 引用 学会求知 学会共处 学会做人 学会做事

    ◆学历不等于能力和水平,学校学到的在社会能用上的只有15%,而在社会能学到85%. ◆世上很多发生的事必有其原因,必有其结果,必有其收获. ◆心态归零,天道酬勤. ◆老板是私营企业家,赚了小钱是自己的 ...

最新文章

  1. 重磅:Python/Java/C 2020年之争!谁是你心中的NO.1?
  2. 最小割 ---- 二分图最大独立集(集合冲突模型) ---- 骑士共存 方格取数(网络流24题)
  3. 2021.12.17自制望远镜调焦座材料
  4. 如何设计一个安全对外的接口
  5. 怎么将翼型导入catia_CATIA导入翼型出现了问题,翼型是在网上找的。说是样条线运算有问题 - 机械 - 小木虫 - 学术 科研 互动社区...
  6. Python查找列表中相加等于s的n个数字(combinations的使用)
  7. 算法学习(三)堆排序
  8. 正则表达式(三)操作符的运算优先级、全部符号的解释
  9. [我给Unity官方视频教程做中文字幕]beginner Graphics – Lessons系列之灯光介绍Lights...
  10. FANUC Robot 编程教程
  11. 数据分析软件SPSS22的授权及汉化
  12. C++ 优先队列 priority_queue 使用篇
  13. java闰年_编写java程序判断闰年。
  14. Win7中删除桌面IE图标
  15. 特征放缩(Feature scaling)
  16. 大数据时代的“被遗忘权”之争
  17. 【视频】谁说程序员无趣?这么多只有资深程序员才看懂的段子,会心一笑,深夜释放压力,随着视频哈哈哈哈哈笑出鹅声!
  18. 2022年全球及中国疏水阀行业头部企业市场占有率及排名调研报告
  19. 408计算机专业统考哪些科目,408计算机考研统考科目难度分析-计算机操作系统...
  20. c语言题库选择填空题,C语言题库(填空题部分)

热门文章

  1. 哈夫曼树结构及带权路径长度
  2. Relu激活函数的多种变体
  3. 大端小端模式及其判别方式
  4. elementui 校验不可以输入空格
  5. 微信开发者工具更新版本后,模拟器显示与真机不一致
  6. 英文儿歌宝宝歌曲幼儿园歌曲童谣等1912首打包下载
  7. 驾驶证——科目一技巧(一)
  8. [编程题] 牛牛的游戏
  9. PageHelper使用及常见失效问题
  10. 英语学习之AJ听力坚持