最近学习严老师的数据结构,发现很多函数声明时都会使用到引用,首先呢,我们要说的是,“引用”是C++中的概念,因为我没接触过C++,所以只能简单地看来看两者的区别。
首先,我们先来看看指针、指针变量和引用的概念。
指针:即内存地址。
指针变量:存放内存地址的变量,即指针变量的值为指针。
引用:某块内存的“别名”,给一个已经存在的变量起一个“别名”。
注意:
指针变量的定义:
int num = 18;
int* p = # //指针变量p的值就是num的内存地址
引用变量的定义:
//引用是C++中的概念!!!
int num = 18;
int &r = num; //引用变量r就相当于num的“别名”
注意:引用类型必须和引用实体是同种类型的,即变量是int型,则引用变量也必须是int型。
这一点倒是和指针很相似,关于指针类型和变量类型不兼容的问题,可以看《C语言_地址与指针类型不兼容造成的影响》)。
引用的主要用途:修饰函数的形参和返回值。
在C++中,函数的参数和返回值的传递方式有三种,分别为值传递、指针传递和引用传递。其中,引用具有指针的效率,又具有变量使用的方便性和直观性。
实际上引用可以做的事,指针都可以做,那为何还需要“引用”呢?
引用体现了最小特权原则,即给予程序元素完成其功能的最小权限,指针能够毫无约束的操作内存中的任何东西,功能很强大,但也很危险。
上面说了,引用可以做的事,指针都可以做,但是两者还是存在一定区别的。
引用一般都是通过指针来实现的,只不过编译器帮我们完成了转换。
我没学过汇编语言,但是我咨询了我的舍友大佬,他们通过编译器调试观察反汇编语言发现,引用和指针的反汇编语言是一样的,就是编译器帮我们完成了转换。
底层实现:引用通过指针实现,定义一个引用类型的变量相当于定义于一个指针类型的变量。
注意,引用是”别名“,不是指针,并没有发生拷贝,我们可以认为“引用”是“简单版的指针”。
#include "stdio.h"
void modifyNumByPoint(int *p);
void modifyNumByReference(int &r);
int main() {
int num01 = 18;
int *p = &num01;
printf("num01 = %d\n", num01);
modifyNumByPoint(p);
printf("modifyNumByPoint--num01 = %d\n", num01);
printf("==========================\n");
int num02 = 20;
int &r = num02;
printf("num02 = %d\n", num02);
modifyNumByReference(r);
printf("modifyNumByReference--num02 = %d\n", num02);
}
void modifyNumByPoint(int *p) {
(*p)++;
}
void modifyNumByReference(int &r) {
r++;
}
结果:
num01 = 18
modifyNumByPoint--num01 = 19
==========================
num02 = 20
modifyNumByReference--num02 = 21
如果是在子函数内修改主函数的一级指针,一般在数据结构中用得比较多,如链表等等,则可如下定义:
//引用
void modifyByReference(int *&){
p = ……;
……
}
//指针
void modifyByPoint(int **p){
*p = ……;
……
}
注:如有错误,敬请指正!!!