在C语言中,我们往往会遇见复杂的指针(如数据结构之中的二级指针),理解起来比较复杂,C++对此加入了引用的概念。 指针和引用的大部分功能类似,是重叠的。 C++的引用可以在较为复杂的情况下进行一定替换,让代码变得更加简洁 但是不能完全替代指针!!!
C++中提出了一个新概念:引用 引用为对象起一个别名 ,与对象使用同一内存空间。 打个比方:孙悟空,又叫孙行者,又叫孙大圣,还叫齐天大圣。这个四个名字都指向同一个人。
我们来看一个样例:
必须初始化
这样写就会报错:
E0252 引用 变量 "b" 需要初始值设定项
对于引用的不可修改性,导致它不能完全替代指针。 就比如链表中,如果将前后指针换位引用,就会导致我们成功进行。
如图的双向链表就不能将中间的链表不能成功删除。因为无法改变引用指向。
int main() {
const int a = 10;
int& ra = a; // 该语句编译时会出错,a为常量
const int& ra = a;
int& b = 10; // 该语句编译时会出错,b为常量
const int& b = 10;
double d = 12.34;
int& rd = d; // 该语句编译时会出错,类型不同
const int& rd = d;
return 0;
}
引用变量是不可改变的左值
我们回想一下C语言的交换函数:
void swap(int* pa ,int* pb){
int tmp = *pa;
*pa = *pb;
*pb = tmp;
return;
}
int main(){
int a = 2 ;
int b = 8 ;
swap(&a,&b);
return 0;
}
而再C++中我们不再需要使用指针
void swap(int& a, int& b) {
int tmp = a;
a = b;
b = tmp;
return;
}
int main() {
int a = 2;
int b = 8;
swap(a, b);
return 0;
}
作为一种数据类型,那一定可以作为返回值来写函数。如下:
int& Count()
{
//...
//延长生命周期,防止销毁
static int n = 0;
n++;
// ...
return n;
}
来看一段错误使用样例:
int& Add(int a, int b)
{
int c = a + b;
return c;
}
int main()
{
int& ret = Add(1, 2);
Add(3, 4);
cout << "Add(1, 2) is :"<< ret <<endl;
return 0;
}
来看看运行效果
为什么会出现这种情况???
总的来说,就是地址上储存的值被改变了。
以值作为参数或者返回值类型,在传参和返回期间, 函数不会直接传递实参或者将变量本身直接返回, 而是传递实参或者返回变量的一份临时的拷贝, 因此用值作为参数或者返回值类型,效率是非常低下的,尤其是当参数或者返回值类型非常大时,效率就更低。 而对于传引用操作相当于返回一个“指针”, 来看比较:
很明显的效率差异。
引用和指针区别: 语法:
底层: 汇编层面上,没有引用,都是指针,引用编译后也转换成指针了