目录
1 引用
1.1 含义
变量的别名(第二名称)
1.2 作用
使用别名访问原名的内存空间,即别名与原名保存同样的内存空间
1.3 语法
数据类型 + & + 别名 + 原名;
如 int &b=a;
1.4 注意
1.4.1 引用必须要初始化
对于一个变量a
,不能直接写int &b;
而需要写int &b=a;
1.4.2 引用在初始化后不可修改
即不可再指向别的内存空间
1.5 引用作函数参数:
作用:函数传参时,可以使用引用使得形参修饰实参
下面以 交换数字 的函数来做说明
void Swap01(int a, int b)
{ // 值传递,不改变实参
int tmp = a;
a = b;
b = tmp;
}
void Swap02(int* a, int* b)
{ // 址传递,改变实参
int tmp = *a;
*a = *b;
*b = tmp;
}
void Swap03(int &a, int &b)
{ // &a直接访问实参中的a空间,实现修改实参的效果
int tmp = a;
a = b;
b = tmp;
}
在一定程度上简化了指针修改实参
1.6 引用作函数返回值
作用:可以作为函数的返回值存在
注意:不要返回局部变量引用
1.6.1 如果返回了局部变量引用
int& test01()
{
int a = 10;
return a; // a作为局部变量,在栈区 ,函数运行完即销毁,这里仍返回
}
int main()
{
int& ref1 = test01();
cout << "ref= " << ref1 << endl; // 第一次编译器做了保留,仍能打印
cout << "ref= " << ref1 << endl; // 第二次即销毁
}
1.6.2 作为函数左值
int& test02()
{
static int a = 10;
return a; // a作为静态变量,在全局区,程序运行完由系统释放
}
int main()
{
int& ref2 = test02();
cout << "ref= " << ref2 << endl;
cout << "ref= " << ref2 << endl;
cout << "ref= " << ref2 << endl; // a在静态区,无论打印多少次,数据都存在
cout << "ref= " << ref2 << endl;
test02() = 1000; // 函数作左值,返回引用
//等价于 a = 1000; 在原名上直接修改
cout << "ref= " << ref2 << endl;// 在别名上访问
cout << "ref= " << ref2 << endl;
cout << "ref= " << ref2 << endl;
cout << "ref= " << ref2 << endl;
}
1.7 引用的本质
本质:在C++内部,引用的实现即一个指针常量
1.7.1 示例1
int main()
{
int a = 101;
int& ref = a;// 这里相当于 int *const ref = &a; 即ref是一个指针
ref = 202; // 这里即 *ref = 202; 不过是编译器自动实现解引用*改变a,不需要我们写*
cout << ref << endl;
cout << a << endl;
return 0;
}
1.7.2 示例2
void func(int& ref) // 相当于 int* const ref = &a;
{
ref = 303; // ref引用,自动转化为 *ref = 303;
}
int main()
{
int a = 101;
func(a);
cout << a << endl;
return 0;
}
总结:推荐使用,较为方便
1.8 常量引用
作用:用来修饰形参,防止误操作
在具体的函数形参列表中,可以加上const以防止形参改变实参
1.8.1 示例1
对于这两段代码是可行的
int a = 10; // 先创建变量 a ,再对a引用
int& ref1 = a;
而这个不可行
int& ref2 = 20; // 直接引用一串数字 20
引用需要一块合法的内存空间
而在此基础上,加上const
const int& ref3 = 30;
// 相当于 int tmp = 30; const int& ref3 = tmp;
此时的ref3
是一个临时空间,我们无法直接访问,因此无法再修改
1.8.2 具体的使用场景
void Print(int& ref)
{
cout << "a= " <<ref<< endl;
}
int main()
{
int a = 10;
Print(a);
}
对于这样一个打印函数,引用作函数参数,正常情况下,只打印a
的数据
但是,如果在函数内加上赋值
void Print(int& ref)
{
ref = 20; // 不小心赋值
cout << "a= " <<ref<< endl;
}
则将改变a
的值,而该函数只为了实现打印功能而不是修改,这就造成误操作
因此,在引用上加const
void Print(const int& ref)
{
ref = 20;
cout << "a= " <<ref<< endl;
}
直接报错,编译不通过,这就实现了防止误操作的功能