【秋招Learning_note】| 拿捏C++引用和指针!

引言

《引用》属于C++的关键知识点,在各个项目中的应用非常广泛,掌握引用的相关知识点和使用方法,能够编写出更加简洁、安全和高效的代码,本篇文章整理总结了引用中的关键知识点。也许之前已经接触过了引用,但是没有详细的项目深入使用的话对引用的理解可能还会存在误区,在开始学习前,先思考一下图片中的几个问题,这几个问题也是在笔试或面试中常见的考点,文章将从这几个问题展开讲述。
请添加图片描述

概念梳理

本文主要介绍的是C++中的引用和指针,所以首先简单介绍C++中引用和指针的相关概念,对相关知识进行回顾。

引用

C++中的引用(Reference)是一种复合类型,它提供了对另一个变量的直接访问方式,就像它是那个变量的别名一样。引用在底层实现上通常是通过指针来完成的,但在语法和用法上,它们比指针更加直观和安全。

指针

C++中的指针(Pointer)是一种变量类型,它存储的是另一个变量的内存地址,而不是数据本身。通过指针,我们可以直接访问和操作存储在内存中的数据,而不需要通过变量名。

引用和指针的区别

通过上述概念可以直接理解,引用它是一个 变量的别名 ,而指针是 存储变量地址的对象 。为了能够更直观的了解指针和引用的区别,可以通过观察引用和指针在使用时底层汇编语言的区别,观察下图可以加深了解。
在这里插入图片描述

a = 30; 在汇编中首先通过 mov eax,dword ptr [a] 获取 a(实际上是 x 的地址)到 eax,然后通过 mov dword ptr [eax],1Eh 将值 30(十六进制为 1Eh)存储到 eax 指向的地址(即 x 的地址)中。这里体现了引用的直接性,操作 a 就像直接操作 x 一样。

*p = 40; 在汇编中首先通过 mov eax,dword ptr [p] 获取 p(y 的地址的地址)到 eax,然后通过 mov dword ptr [eax],28h 将值 40(十六进制为 28h)存储到 eax 指向的地址(即 p 指向的地址,也就是 y 的地址)中。这里需要先通过 p 获取 y 的地址,然后才能操作 y 的值,体现了指针的间接性。

引用和指针在底层汇编语言中的语法都是一致的,所以说引用是更加安全的指针。它们之间的区别主要是下面两条。

①初始化要求

  • 引用 必须在声明时被初始化,且一旦与某个变量绑定后,就不能再改变为引用另一个变量。也就是说引用变量的关联对象一旦确认以后就不能发生改变,不能与其他的对象进行关联。
  • 指针 在声明时可以不初始化(虽然这通常不是个好习惯),并且可以在任何时候重新指向其它地址。

②安全性问题

  • 引用 在语法上更接近于直接使用变量,因此可以减少一些由于指针错误(如解引用空指针、野指针等)导致的错误。
  • 指针 提供了更大的灵活性,但也带来了更高的出错风险。需要更加小心地管理内存和指针的生命周期。

所以也可以说引用时一种更安全的指针,因为引用对象永远能够引用到对应内存,指针可能是一个空指针

总结
引用和指针的区别在于:从定义中来看,①引用是一种复合类型,而指针是一个变量类型;②引用提供了对另一个变量的直接访问方式,指针存储的是另一个变量的内存地址。

引用使用时注意的点

①必须完成初始化
②对于左值引用来说,初始化的对象能够取到地址(为左值变量)
在这里插入图片描述

在这里插入图片描述

函数中的使用

例如我们在书写swap函数的时候想要实现对数值的交换,可以有多种写法

void swap1(int a, int b) 
{
	int temp = a;
	a = b;
	b = a;
}

对于swap1,函数试图通过值传递来交换两个整数的值。然而,由于参数是通过值传递的,函数内对a和b的任何修改都不会影响传递给函数的原始变量。因此,这个函数实际上不会改变任何外部变量的值。
底层原理:
在调用swap1时,传递给函数的实际上是原始变量a和b的副本。函数内部对这两个副本的操作不会反映到原始变量上。

void swap2(int* a, int* b)  // 接收变量的地址
{
	int temp = *a;
	*a = *b;
	*b = temp;
}

对于swap2,这个函数通过指针传递来交换两个整数的值。参数a、b是变量的地址,是指向整数的指针,函数内部对指针解引用后的值进行的修改会直接影响原始变量。
底层原理:
在调用swap2时,传递给函数的是指向原始变量a和b的指针。函数内部通过解引用这些指针来访问和修改原始变量的值。

void swap3(int& a, int& b)
{
	int temp = a;
	a = b;
	b = temp;
}

swap3函数使用了引用传递的方式来接收参数。这意味着,当我们将两个变量的名字(例如x和y)传递给swap3时,我们实际上是在告诉这个函数:“嘿,swap3,你直接操作这两个变量本身,而不仅仅是它们的副本。”这是通过int&(即整型引用的声明)来实现的。

左值引用和右值引用的区别

在C++11以后加入了右值引用这一概念,在认识右值引用前,先了解一下C++中左值和右值的概念。

  • 左值是可以出现在赋值语句左边的表达式。它们表示持久的对象,具有稳定的内存地址。左值可以是变量、函数返回值(如果返回的是引用或指针)、解引用的指针等。左值可以被多次赋值,即可以在其生命周期内被修改。
  • 右值通常表示临时的、非持久的数据,它们通常没有稳定的内存地址(虽然这并非绝对,比如某些实现可能会为右值提供存储位置以优化性能)。右值包括字面常量、表达式计算结果(除非该表达式的结果是引用类型)、函数调用(除非返回类型是引用或指针)等。

了解了左值和右值能够更好理解左值引用和右值引用的区别。

左值引用是我们在C++中经常遇到的引用类型。它是对左值的一个别名,通过引用可以直接访问和修改左值。左值引用用&符号表示,但注意这里的&是引用声明的一部分,不是取地址运算符。

int a = 10;
int &b = a;

右值引用是C++11引入的新特性,用于引用右值。通过右值引用,我们可以访问和修改那些即将被销毁的临时对象,从而可以实现资源的转移(如移动语义)而非拷贝,从而提高程序的性能。右值引用用&&符号表示。

int &&c = 20;

在这里c作为右值引用变量,但是它本身是一个左值 ,只能使用左值对他进行引用
例如

c = 30; √ 对于右值引用变量能够对他重新赋其他右值对象。
int &&d = c; × 语法错误,c实际上是一个左值对象无法将右值引用绑定到左值
int &e = c; √ 使用左值引用绑定左值是正确的。

总结

引用和指针都是C++中非常重要的知识点,是笔试面试中常出现的考点,掌握这部分内容能够大大提高代码效率。
文章通过讲解C++代码的底层汇编语言来了解其中的特性,有些人获取不知道汇编语言该如何开启,可以参考http://t.csdnimg.cn/AP5bn这篇文章中的方式。希望能够帮到各位!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值