C++ 中的指针和引用

指针大小

指针大小与编译环境有关,而与机器无关,64位编译环境下是8个字节,32位下是4个字节

指针类型

int *p[10]
int (*p)[10]
int *p(int)
int (*p)(int)

  1. 表示指针数组,数组内有十个指向int类型的指针变量
  2. 指向一个大小为10的int数组
  3. 函数声明,函数名是p,参数是int类型,返回值int*
  4. 函数指针,指向具有int类型参数,返回值是int类型的函数

常量指针和指针常量

指针常量是一个指针,指向一个只读变量,可以写作int const *p或const int *p。
常量指针是一个不能给改变指向的指针,如int *const p。

主要是看const修饰谁,修饰*p还是p

a和&a有什么区别

假设数组int a[10]; int (*p)[10] = &a;其中:

  • a是数组名,是数组首元素地址,+1表示地址值加上一个int类型的大小,*(a + 1) = a[1]。
  • &a是数组的指针,其类型为int (*)[10],其加1时,系统会认为是数组首地址加上整个数组的偏移(10个int型变量),值为数组a尾元素后一个元素的地址

数组名和指针的区别

相同

可以通过偏移来访问数组中的元素

不同

数组名不能自增或者自减,但是数组名作为参数传递的时候就可以自增、自减了。这个时候使用sizeof得到的是指针的大小

野指针和悬空指针

野指针是没有被初始化过的指针,悬空指针是指针指向了已经释放内存并且没有及时置空的一种指针。所以C++引入了智能指针,避免悬空指针的出现。

数组和指针的区别

  1. 用sizeof可以计算出数组字节数;对于指针得到的是一个指针变量的字节数
  2. 编译器为了简化对数组的支持,实际上是利用指针实现了对数组的支持也就是将表达式中的数组元素引用转换为指针加偏移量的引用。
  3. 作为参数传递的时候,传递过去的是首地址
  4. 数组原来的地址是固定的,指针不是固定的。

指针和引用的区别

  1. 指针本质是一个变量,存储一个地址;引用是原来变量的别名
  2. 指针可以多级;引用只有一级
  3. 指针可以为空,引用不能
  4. 指针在初始化之后可以改变指向;引用不可以

因为程序在编译的时候,会将指针和引用添加到符号表上,符号表中记录的是变量名和变量对应的地址。
指针变量在符号表上的地址值是指针变量的地址值;引用对应的是引用对象的地址值。
符号表生成之后不能修改,所以可以通过改变指针变量的值也就是指向的对象,而引用不能修改

  1. sizeof指针得到的是指针大小;而引用是指向变量的大小
  2. 指针作为参数传递的时候,也只是将实参的一个拷贝传递给形参,在函数里面改变这个参数并不会改变参数的值,而引用可以。
  • 指针参数传递本质上是值传递,传递的是一个*地址值,会在栈中开辟内存空间以存放由主调函数传递进来的实参值,从而形成实参的一个副本
  • 引用参数传递的过程中,被盗函数的形式参数也是在栈中开辟了内存空间存放局部变量,但是存放的是由主调函数传进来的实参变量的地址,被调函数对于形参的任何操作都被处理成间接寻址。因此,被调函数对于形参的任何操作都会影响主调函数中的实参变量。
  1. 声明指针的时候可以不用初始化,但是引用必须初始化
  2. 指针可以指向空值,但是引用不可以
  3. 引用比指针安全,因为不会产生野指针

指针和引用适用场景

1、对栈空间大小敏感的时候,因为引用传递不需要临时变量
2、类对象传递引用。首先传值的话会消耗很大的空间,其次如果参数是类对象,就是值传递,就要复制,复制就要调拷贝构造函数,开销很大。
3、需要返回函数内局部变量的内存的时候用指针。使用指针传参需要开辟内存,用完要记得释放指针,不然会内存泄漏。函数内部new分配的内存的引用是不能返回的,最后也无法释放造成memory leak
4、如果数据对象很小,如内置数据类型或者小型结构,可以按照值传递

值传递、指针传递、引用传递

  • 值传递:有一个形参向函数所属的栈拷贝数据的过程,如果值传递的对象是类对象 或是大的结构体对象,将耗费一定的时间和空间。(传值)

  • 指针传递(传递的是地址):同样有一个形参向函数所属的栈拷贝数据的过程,但拷贝的数据是一个固定为4字节的地址。

  • 引用传递(传递的是地址):同样有上述的数据拷贝过程,但其是针对地址的,相当于为该数据所在的地址起了一个别名。

效率上讲,指针传递和引用传递比值传递效率高,一般主张使用引用传递。

函数参数使用引用的好处

  • 被调函数中的形参成为原来主调函数中的实参变量的一个别名
  • 在函数中是直接对实参操作的,在内存中没有产生副本
  • 如果使用指针当形参,虽然也能达到与引用相同的效果,但是在被调函数中同样要给形参分配存储单元,而且重复使用“*指针变量名”的形式运算,阅读性差容易出错
  • 在主调函数的调用点处,必须用变量地址做实参,引用更容易使用,更清晰。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值