引用
引用的基本使用
-
作用:给变量起别名
-
定义:
数据类型 & 引用名 变量;
-
注意点:引用在定义时必须初始化,初始化之后不能改变
int a = 10, b = 20; int &x = a; x = b; // 注意:这是赋值操作,并没有改变引用的指向,x仍然是a的别名
引用作为函数形参
- 作用:类似于地址传递,可以改变实参的值,但比地址传递更简单
//1. 值传递
void mySwap01(int a, int b) {
int temp = a;
a = b;
b = temp;
}
//2. 地址传递
void mySwap02(int* a, int* b) {
int temp = *a;
*a = *b;
*b = temp;
}
//3. 引用传递
void mySwap03(int& a, int& b) {
int temp = a;
a = b;
b = temp;
}
int main() {
int a = 10;
int b = 20;
mySwap01(a, b);
cout << "a:" << a << " b:" << b << endl;
mySwap02(&a, &b);
cout << "a:" << a << " b:" << b << endl;
mySwap03(a, b); // 引用传递
cout << "a:" << a << " b:" << b << endl;
return 0;
}
引用作为函数返回值
注意:不要返回局部变量的引用;函数调用可以作为左值!
int& func() {
int local = 10;
int& a = local;
return a;
}
//返回静态变量引用
int& test02() {
static int a = 20;
return a;
}
int main() {
int& ref = func();
cout << "ref=" << ref << endl; // vs中可以输出一次,是因为编译器对这个值做了一次暂留
cout << "ref=" << ref << endl; // 输出值不对
//如果函数做左值,那么必须返回引用
int& ref2 = test02();
cout << "ref2 = " << ref2 << endl;
cout << "ref2 = " << ref2 << endl;
}
// mac下编译报错
test.cpp:6:10: warning: reference to stack memory associated with local variable 'local' returned [-Wreturn-stack-address]
return a;
^
test.cpp:5:8: note: binding reference variable 'a' here
int& a = local;
^ ~~~~~
1 warning generated.
引用的本质:内部实现就是指针常量
//发现是引用,转换为 int* const ref = &a;
void func(int& ref){
ref = 100; // ref是引用,转换为*ref = 100
}
int main(){
int a = 10;
//自动转换为 int* const ref = &a; 指针常量是指针指向不可改,也说明为什么引用不可更改
int& ref = a;
ref = 20; //内部发现ref是引用,自动帮我们转换为: *ref = 20;
cout << "a:" << a << endl;
cout << "ref:" << ref << endl;
func(a);
return 0;
}
常量引用
常用用法:用在函数形参下,表示形参值不能改变
注意:引用不可以用数值 初始化,但是常量引用可以初始化为数值 初始化
//引用使用的场景,通常用来修饰形参
void showValue(const int& v) {
//v += 10;
cout << v << endl;
}
int main() {
//int& ref = 10; 引用本身需要一个合法的内存空间,因此这行错误
//加入const就可以了,编译器优化代码,int temp = 10; const int& ref = temp;
const int& ref = 10;
//ref = 100; //加入const后不可以修改变量
cout << ref << endl;
//函数中利用常量引用防止误操作修改实参
int a = 10;
showValue(a);
return 0;
}