(一)引用
(1)引用传入
表层:给内存块起的别名
int a = 10;
int &b = a;
底层:C++中和指针的处理方式相同,即在用到引用的地方,就会自动进行解引用。相当于下面这段代码
int a = 10;
int *b = &a;
(2)特点
- 引用必须初始化
int a = 10;
int &b ;//错误
int &b = a;//正确
- 引用初始化的变量一定要可以取地址
int a = 10;
int &b = 10;//错误
像10这样的立即数是存放在寄存器当中的,是不能对立即数取地址的;
- 引用是不可改变的
int a = 10;
int c = 20;
int &b = a;
&b = c;//错误
- 引用只能访问引用变量所引用的内存单元
int a = 10;
int c = 20;
int &b = a;
cout << b << endl;//10
cout << &b << endl;//&a
(二)const和引用结合
(1)
int a = 10;
int &b = a;
int &c = 20;//错误
分析:这三行是对引用的一般使用,根据引用的特点是它的初始化的变量必须可以取地址,但20这样的立即数不可以。因此,可以利用const修饰,形成常引用,常引用是可以引用立即数的,此时将立即数存放到临时变量中,常引用来引用临时变量。
正确的写法如下:
const int &c = 20;//引用的是临时量
(2)
const int a = 10;
int &b = a;//错误
分析:a是常量内存块,b和a的内存保持一致,存在修改的风险,加const杜绝。修改:const int & b = a;
(3)
int a = 10;
const int &b = a;//const int <== int
判断条件:左操作数的权限 <= 右操作数的权限
除去一种特殊情况即左const int *;对应的右为int *这是是错误的。
(4)
int a = 10;
int *p = &a;
int *&q = p;
分析:q是p的别名,p,q均为一级指针,左右操作权限相等,正确。
(5)
int a = 10;
const int *p = &a;
int *&q = p;//int * <= const int *错误
分析:第三句左操作数的权限大于右操作数的权限,错误。
修改:
const int *&q = p;
(6)
int a = 10;
int *const p = &a;
int *&q = p;//左:int *,右:int * const 错误
分析:左操作数的权限大于右操作数的权限,错误。
修改:
int *const &q= p;
(7)
int a = 10;
int * p = &a;
const int *&q = p;//左:const int * ;右:int *,特殊情况,错误
分析:隐藏的将int **转换为了const int **,这是错误的,有修改常量内存块的风险。
修改:
int a = 10;
int * p = &a;
const int * const &q = p;
或:
int a = 10;
const int * p = &a;
const int * &q = p;
(8)
int a = 10;
int * p = &a;
int *const&q = p;//左:int *const ;右:int *
分析:左操作数的权限小于右操作数的权限,正确。
(三)const、引用与形参的结合
形参加上const:
- 防止实参被修改;
- 可以用来引用立即数;
引用做形参和普通变量做形参的区别:
- 引用修改实参的值;
- 引用不能引用立即数,部分实参无法调用;