引用的基本语法
作用:给变量起别名
语法:数据类型 &别名 = 原名;
引用的注意事项
- 引用必须初始化
- 引用初始化之后不能再改变
#include <iostream>
using namespace std;
int main()
{
int a = 20, c = 40;
// int &b; //1.引用必须初始化
int &b = a;
b = 30;
// &b = c; //2.引用初始化之后不能再改变
cout << "a = " << a << endl;
return 0;
}
引用做函数参数
作用:函数传参时,可以利用引用传递修饰形参
优点:可以简化指针传递
#include <iostream>
using namespace std;
void swap1(int *a, int *b)
{
int t = *a;
*a = *b;
*b = t;
}
// &a = a, &b = b; a是a的别名 b是b的别名
void swap2(int &a, int &b)
{
int t = a;
a = b;
b = t;
}
int main()
{
int a = 1, b = 2;
swap1(&a, &b);
cout << " a = " << a << " b = " << b << endl;
swap2(a, b);
cout << " a = " << a << " b = " << b << endl;
return 0;
}
引用做函数返回值
作用:引用是可以作为函数返回值存在的
注意:不要返回局部变量引用
用法:函数调用作为左值
#include <iostream>
using namespace std;
int& text1()
{
int a = 10; //局部变量存放在在栈区,函数结束后变量被释放
return a;
}
int& text2()
{
static int a = 10; //静态变量存放在全局区,程序结束后变量被释放
return a;
}
int main()
{
int& ref = text1();
cout << "ref = " << ref << endl; //变量中的值被系统保存了一次
cout << "ref = " << ref << endl;
int& ref2 = text2();
cout << "ref = " << ref2 << endl;
cout << "ref = " << ref2 << endl;
text2() = 20;
cout << "ref = " << ref2 << endl;
return 0;
}
上述代码中两个text返回值均为变量的引用,但text1返回了局部变量引用,在函数结束后局部变量被释放,就不能通过引用访问局部变量,(在第一次调用时系统保护了局部变量的值,所以还能原样输出),text2返回全局变量引用,在函数结束后全局变量不会被释放,所以可以通过引用访问。
返回值为引用的函数也可以作为左值,所代表的操作就是返回变量的引用,再通过引用来修改函数中的变量。
引用的本质
本质:引用的本质在c++内部实现是一个指针常量。
例如int类型的引用,其本质就是int * const,即不可以改变指针的指向,但可以通过指针访问来改变变量的值。
int &ref = a 等价于 int * const ref = &a;
由此,就解释了为什么引用必须初始化,为什么引用在初始化之后就不可以改变。
都是因为指针常量本身是个常量,必须初始化且不能被改变。
常量引用
作用:常量引用主要用来修饰形参,防止误操作。
在函数形参列表中,可以加const修饰形参,防止形参通过引用修改实参。
#include <iostream>
using namespace std;
void text0(int &a)
{
a = 10;
cout << "a = " << a << endl;
}
void text1(const int &a)
{
// a = 10;
cout << "a = " << a << endl;
}
int main()
{
int a = 0;
text0(a);
text1(a);
return 0;
}
例如在上述代码中,text类的函数作用是打印a的值,但在text0中,误操作将a值变为了10,而在text1中,因为引用被常量修饰,相当于const int * cont a = &a,既不可以修改指针的指向,也不可以通过指针来修改变量的值,这样在发生误操作 a = 10,时,编译器就会报错(这里将报错的操作注释起来)。