指针和引用的区别
指针和引用都是地址的概念。
指针:是保存另一个变量内存地址的变量,指针通过 * 访问保存的内存地址所指向的值;
引用:是另一个变量的别名,一旦被初始化就不能被改变,引用可以认为是一个具有自动间接性的常量指针,相当于编译器帮助实现了自动间接性取值,即:编译器帮助加上了 * 。引用内部实现为指针。
指针是在 C 语言中就已存在,功能非常强大,但是许多的不安全因素也都是指针导致的。引用是 C++ 中引入的概念,引用使用起来更加安全。
但是,C++引入引用的直接原因是支持 C++ 重载,来看下面一个例子:
#include <iostream>
using namespace std;
int main()
{
int x = 10;
int *p = &x;
int &y = x;
cout<<"*p = "<<*p<<endl;
cout<<" y = "<<y<<endl;
}
输出为:
*p = 10
y = 10
上面的例子可以通过下图来理解:
变量 p 存储 x 的地址,x 和 y 都是 10 的名称。
接下来详细的讲解一下指针和引用的区别。
初始化
- 引用在定义时必须被初始化,因为它直接指向一个已存在的对象;
- 指针在定义时不必立即初始化,可以在后续赋值。
可变性
- 引用一旦初始化为指向某个对象,就不能改变为指向其他对象;
- 指针可以随时改变指向另一个同类型的对象。
空值
- 引用不能为空,它总是指向某个对象;
- 指针可以为空,允许指向空值。
解引用
- 使用引用时,不需要解引用操作(如使用 * 运算符)来访问所指向的值;
- 指针需要使用 * 运算符来解引用以访问所指向的值。
内存占用
- 引用在声明时不需要分配额外的内存空间,因为它仅仅是原变量的别名;
- 指针需要占用一定的内存空间,因为它存储的是另一个变量的地址。
安全性
- 引用被认为是更安全的,因为它们不能被设置为空,且一旦初始化后就不可改变;
- 指针可能被设置为空或指向不同的对象,因此在使用时可能需要额外的空值检查,从而增加了出错的可能性。
编译时处理
- 编译器在编译时将引用添加到符号表中,记录的是引用对象的地址;
- 编译器在编译时将指针添加到符号表中,记录的是指针变量的地址。
sizeof
- 对引用使用 sizeof 得到的是变量的大小;
- 对指针使用 sizeof 得到的是变量的地址的大小。
级数
理论上指针的级数没有限制,但引用只有一级。即不存在引用的引用,但可以有指针的指针。
运算能力
- 指针可以进行算术运算,如加减法,这些运算实际上是对指针所指向的内存地址进行操作;
- 引用不能进行这样的运算,或者说效果不一样。例如就++操作而言,对引用的操作直接反应到所指向的对象,而不是改变指向。