[C++] C++引用如何使用,和指针有何区别

image.png

本文来谈谈C++中的引用,引用的出现呢,其实是为了弥补C语言的语法不足,java 等其他语言中都有引用的概念,唯独C没有,我们来往下看

1.引用概念

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

有一个很好的例子, 比如大家都玩LOL , 但是它本身叫英雄联盟
image.png
比如说他, 有人叫他烬, 有人叫他瘸子,但是说的都是它,引用当前是可以这样理解的

2.引用使用

基础语法:

引用的基础语法是这样使用的

类型& 引用变量名(就是要起的别名) = 引用实体;

举个栗子
image.png

大家可以看到, a的值和b的值相同,a的地址和b的地址相同
**所以说在语法层次,b就是a的别名 **

需要注意的一个问题就是**引用类型必须和引用实体是同种类型的 **
image.png

一般编译器报这种红线都是发生了错误

image.png

3.引用特性

引用有好几个特性, 都是非常值得注意的地方

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

其实这几个定义特性都是比较好理解的

引用在定义时必须初始化

类比生活中就是,你要给人别人起别名,你总得给知道给谁起吧, 我起个别名, 我不知道我给谁起
这合理吗
8f1001e95baa401fa5c718e3d8f51a7.png

所以引用在定义时一定要初始化
image.png

一个变量可以有多个引用

这个其实也好理解, 比如你家里人会叫的乳名/小名, 你妈妈生气的时候就会大声呼喊你的大名,你对象可能叫你baobao…你舍友可能会给你起各种各样的外号, 但是终究还是你
image.png

image.png

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

这样说吧,你今天管你室友A叫 小黑,明天管室友b叫小黑, 后天管室友c叫小黑, 我感觉你得挨揍,
我们一般都是起别名都是固定的人的

image.png
image.png

所以可以看到,编译器根本不会管你想要修改引用

常引用

引用这里有一个权限的概念,我们来往下看

假设下面一个场景
const int a = 0;
int& b = a;
大家都知道const修饰一个变量,代表这个变量具有常属性, 是不能修改的,那这样定义引用,是否可以修改呢?
我们来试一下,
image.png
这也正常,肯定是不能修改的,这就是说默认b是a 的引用,声明方式为int不具有常属性, 但是a变量本身是具有常属性的

这就是变量是不可以修改的,定义的引用也得是不可以修改的,不可以放大权限

那本身是可以修改的, 可否引用定义为const类型呢
image.png

这就是可以缩小权限,但是不可以放大权限

这样定义的引用自然是不可以修改的,大家可以自己测试一下
引用的这三个特性都是比较好理解的,不需要记忆,通过引用的定义直接就能判断出来
引用类型必须和引用实体是同种类型的

我们来看这样一个例子

image.png
但是如果加上一个const , 就可以用了, 这是为什么呢?
image.png

首先是表达式会生成一个临时变量, 在表达式结束的时候就会被销毁, 而且临时变量具有常属性, 所以使用const修饰就可以通过编译, 使用const&将临时表达式的寿命延长到表达式末尾之后,生命周期拉长

引用的使用场景

1.做参数

大家现在应该基本理解了引用的基本概念,我们来看看引用作为函数参数有何妙用

大家一定写过一个函数, 叫做swap ,用来交换两个数
image.png

C语言的指针问题,对于不少初学者可以一个大难题, 还记得之前写单链表的时候有一个二级指针的使用,不知道大家会使用了没有,顺序表和链表

不知道对于大家怎么想, 我觉得能不用指针解决的问题就不用指针解决,指针的出现可能会带来很多错误
image.png

如果不小心这样传参, 你是否需要在函数内特殊处理

但是引用就不会
image.png

不过引用到底是怎么实现的,还是和指针相关,而且很多指针能做的,引用做不了,比如链表只用引用就实现不了,大家可以试试

image.png

2.引用做返回值

我们写函数的返回值都是直接返回它的类型,那为什么要用引用返回呢,我们来看看

image.png

如果返回的是一个很大的数据呢?? 那么寄存器是存储不下的, 所以调用者就会提前开辟空间来存储

如果我们使用引用返回
image.png

这个代码是存在问题的:

  1. c是Add栈帧中的局部变量,Add调用结束之后就会被释放,所以相当于访问了不属于自己的空间,非法访问
  2. 如果编译器把这块空间给销毁了,那么ret中的值就是随机值,在c语言中,非法读取编译器一般不会报错,如果未清理成随机值,那么看似读取的是正确的,但是本身是错误的

VS下:
image.png

可以看到VS没有把空间清理掉, 但是会爆出警告

有的朋友可能会说,没有错误,因为结果是正确的,那我们来瞅瞅
image.png

这里是用的vs2013, 并没有修改ret,但是确实变化了

我们在Linux下看一眼, 会不会清理
image.png

所以使用引用做返回值,一定要注意的就是,不能返回局部变量
所以一般引用做返回值都是返回没有被释放的空间, 比如静态的变量OR 动态开辟的空间 ,以及对象

引用和指针的区别

引用在语法层面就是起了一个别名,并没有开辟新的空间
但是底层实现: 是通过指针来实现的

image.png

那么引用和指针有什么区别呢???

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

C++引用就暂时说到这里了,在后面学习到更深度的层次就会更有不一样的理解了,目前我只理解到地方啦,大家有问题可以私我一起交流
感谢收看

image.png

  • 25
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 21
    评论
评论 21
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值