首先看一下这两者的定义
指针:是编程语言中的一个对象,利用地址,它的值直接指向(points to)存在电脑存储器中另一个地方的值。由于通过地址能找到所需的变量单元,可以说,地址指向该变量单元。
引用:是某个已知变量 或对象的别名,它不是变量,自身没有值和地址,不占用内存空间。
一:指针和引用的区别
1. 引用必须被初始化,而指针不初始化也没有太大的问题。
引用是一个已知对象或变量的别名,而且它不占内存空间,如果只是单单一个int&a,是没有任何意义的。
指针不一样,int*p;就是在内存中开辟了一块空间,用来存放地址。地址可以在刚开辟空间的时候放入,也可以在需要的时候放入。
一个引用只能对应着一个变量(引用是专一的),一个指针变量却可以存放多个变量或对象的地址(指针是多变的)。
前面也说了,引用是一个一个变量或对象的别名。那么比如张三的别名是阿三,如果李四的别名也叫阿三,当有人叫阿三的时候,到底哪个阿三才会回应呢?这就容易引起混淆了。
指针是一块空间,里面的内容是可以替换的,指针里存的是a的地址,通过指针你可以访问到a,当有需要了,你把指针的值改为了b,你同意还是可以范文到b。不存在空值的引用,但存在空值的指针
引用是一个已知对象或变量的别名,当这个变量都不存在,哪来的别名。引用相对于指针更加安全
引用在定义的时候就被初始化了,并且引用的对象不可改变。正是因为这点,程序中不必对其进行检测。
指针是多变的,很多时候要对它进行判空,因为空指针是不安全的。而且指针的值容易发生变化,在你不经意间,它就已经变成其他的值了。重载操作符的时候必须要用到引用。
最典型的就是[] 的重载,因为数组的返回值是可以作为左值的,而作为左值表示的是一块空间,是可以赋值的。这时就必须用到引用。
int& Array::operator[](int i)//可能作为左值,所以要返回引用
{
static int ret = 0;
if (i > length - 1 || i < 0)
{
cout << "out of range";
return ret;
}
else
return arr[i];
}int main()
{
Array a(6);
for (int i = 0; i < 8; i++)
{
a[i] = i;
cout << a[i];
}
return 0;
}
二:指针和 引用的相同点
1. 指针和引用在底层的实现是一样的
指针
int a = 1;
int*pointer = &a;
return 0;
反汇编
引用
int a = 1;
int&b = a;
return 0;
反汇编
int&a=b类似于指针中的int *const p=&b(指针p的值不可变)
const int&a=b类似于指针中的const int*const p=&b(p和p指向的内容都不可变)引用中一个变量和它的引用必须是同一类型。指针中一个变量和它的指针必须是同一类型