C++引用
using namespace std;
void main() {
int i = 9;
int &ri = i;
cout << "i = " << i << " " << "ri = " << ri << endl;
ri = 20;
cout << "i = " << i << " " << "ri = " << ri << endl;
i = 12;
cout << "i = " << i << " " << "ri = " << ri << endl;
cout << "i 的地址是:" << &i << endl;
cout << "ri 的地址是:" << &ri << endl;
}
/* 运行结果:
i = 9 ri = 9
i = 20 ri = 20
i = 12 ri = 12
i 的地址是: 0029FDB0
ri 的地址是: 0029FDB0
*/
可以看到,ri和i指的实际上是同一个变量(内存地址),对ri的操作实际上就是对i的操作,ri可以看做是i的别名。
使用引用时需要注意以下几个问题:
① 在定义引用时,&在类型与引用名之间的位置是灵活的,故以下几种定义完全等价:
int& ri = i; int & ri = i; int &ri = i;② 在变量声明时出现的&才是引用运算符(包括函数参数声明和函数返回类型的声明),其它地方出现的&则是地址操作符。
int i;
int &r = i; // 引用
int& f(int &i1, int &); // 引用参数(声明参数变量)
int *p = &i; // &取i的地址
cout << &p; // &取p的地址③ 引用必须在定义时初始化,不能在定义完成后再给它赋值;为引用提供的初始值可以是一个变量名,也可以是另一个引用名,也可以是另一个引用名;同一个变量可以定义多个引用。
float f;
float &fr; // error,引用定义时未初始化
float &r1 = f; // r1 <=> f
float &r2 = f; // r2 <=> f
float &r3 = r1; // r3 <=> r1 <=> f
④引用对应着变量的左值,代表变量的内存区域,实际是一种隐式指针,但与指针存在区别。
引用与指针的区别。
void main() {
int i = 9;
int *pi = &i; // 取地址
int &ri = i; // 定义引用
*pi = 2;
ri = 8; // ri等价于*pi
}
可以看到,引用本质上也是指针的一种隐式封装,即将*pi简化为ri。但它与指针至少存在两点区别:
- 指针必须通过解引用运算符”*”才能访问它所指向的内存单元,而引用则与普通变量的访问方法差不多;
- 指针是一个变量,它有自己独立的内存区域,可以对它重新赋值,让它指向其他地址。但引用只是某个变量的别名,甚至没有自己独立的内存区域,必须在定义时进行初始化,并且一经定义就再也不能作为其他变量的引用了。
⑤ 当用&运算符获取一个引用的地址时,实际取出的是引用对应的变量的地址。例如:
int i = 9;
int &ri = i;
int *pi = &ri; // pi的值实际上是i(ri是i的别名引用)的地址
⑥ 建立引用时,引用应当类型匹配。
double d;
int &rd = d; // 引用类型与它对应的变量类型不匹配
⑦ 引用与数组。可以建立数组或数组元素的引用,但不能建立引用数组。
int i = 0, a[10] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10}, *b[10];
int (&ra)[10] = a; // ra是具有10个元素的整型数组的引用
int &aa = a[0]; // 数组元素的引用
int *(&rpa)[10] = b; // rpa是具有10个整型指针的数组的引用
int &ai[10] = a; // error,ai是引用数组(每个数组元素都是引用),这是不允定义的
ra[3] = 0; // 数组引用的用法
rpa[3] = &i; //
⑧ 引用与指针。可以建立指针的引用,但不能创建指向引用的指针。
int i = 0, a[10];
int &*ip = i; // error,ip是指向引用的指针
int *pi = &i;
int *pr = pi; // pr是指针的引用
本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!