引用
- 引用就是操作同一块地址空间,是变量的“别名”,而不是单独的变量,不会单独分配存储单元,所以操作一个变量,引用的变量也会跟着变化;
- 变量不仅可以有多个引用,还可以多重引用。但需要注意的是,定义时必须初始化,且只能作为一个变量的别名不能再成为其他变量的别名(貌似也没有赋值语句能实现);
- 引用不是指针,但和指针常量很类似。
- 不能建立引用的数组,因为它是一系列元素的组合,但是可以建立数组的引用。
#include <iostream>
using namespace std;
void func(int (&array)[3])
{
cout << array[1] << endl;
}
int main()
{
int val;
int& r_val = val;
int& r_val2 = val; // 一个变量可以有多个引用
int& rr_val = r_val; // 多重引用
// int& rr_val2; // 错误:定义时必须初始化
r_val2 = 10;
cout << "val = " << val << " addr: " << &val << endl;
cout << "r_val = " << r_val << " addr: " << &r_val << endl;
cout << "r_val2 = " << r_val2 << " addr: " << &r_val2 << endl;
cout << "rr_val = " << rr_val << " addr: " << &rr_val << endl;
cout << "***************************" << endl;
int val2 = 12;
rr_val = val2; // 这是赋值,并非作为val2的别名
cout << "val2 = " << val2 << " addr: " << &val2 << endl;
cout << "rr_val = " << rr_val << " addr: " << &rr_val << endl;
cout << "***************************" << endl;
int array[3] = {1, 2, 3};
func(array); // 正确:数组的引用 (函数参数,可以对比一下指针)
// int& r_array[3] = array[3]; // 错误:引用的数组
return 0;
}
/*
输出结果:
val = 10 addr: 0x6ffdf4
r_val = 10 addr: 0x6ffdf4
r_val2 = 10 addr: 0x6ffdf4
rr_val = 10 addr: 0x6ffdf4
***************************
val2 = 12 addr: 0x6ffdf0
rr_val = 12 addr: 0x6ffdf4
***************************
2
*/
常引用
前面说到引用是一个“别名”,修改其中一个另外一个也会跟着变化,所以如果不希望引用影响原变量,可以定义为常引用。
int val;
const int& r_val = val;
val = 1; // 正确
r_val = 2; // 错误,有const限定
另外,加上const之后引用的类型可以不同,如:
double d = 3.1415926;
const int &i = d;
加上const还可以引用常量:
const double& d = 12.3;
double& d = 12.3; // 错误,需要加上const限定
引用作为参数
引用作为函数的参数可以改变原本的值,因为函数内部操作引用就相当于操作原变量。
#include <iostream>
using namespace std;
void swap1(int a, int b); // 值传递
void swap2(int *a, int *b); // 指针传递
void swap3(int& a, int& b); // 引用传递
int main()
{
int a, b;
a = 100; b = 200;
swap1(a, b);
cout << "a = " << a << " b = " << b << endl;
a = 100; b = 200;
swap2(&a, &b);
cout << "a = " << a << " b = " << b << endl;
a = 100; b = 200;
swap3(a, b);
cout << "a = " << a << " b = " << b << endl;
return 0;
}
void swap1(int a, int b)
{
int temp = a;
a = b;
b = temp;
}
void swap2(int *a, int *b)
{
int temp = *a;
*a = *b;
*b = temp;
}
void swap3(int& a, int& b)
{
int temp = a;
a = b;
b = temp;
}
引用作为返回值
函数可以返回一个引用,可以免去编译器拷贝返回值这一步骤。但需要注意的是,返回的引用不能是局部自动变量,因为函数结束后栈的内存就被自动释放掉了,和返回指针类似。
#include <iostream>
using namespace std;
int array1[10] = {0};
int &func1(int i)
{
return array1[i];
}
/* 出错,函数运行结束局部自动变量占用的栈内存被释放了
int &func2(int i)
{
int array2[10] = {0};
return array[i];
}
*/
int main()
{
func1(3) = 3; // 这里可以被赋值
cout << "array1[3]: " << array1[3] << endl; // 输出结果:array1[3]: 3
return 0;
}