08.引用
08.引用
目录介绍
- 8.1 引用的概念
- 8.1.1 什么是引用
- 8.1.2 引用的声明
- 8.2 引用的特性
- 8.2.1 引用必须初始化
- 8.2.2 引用不能重新绑定
- 8.2.3 引用访问数据
- 8.3 引用与指针
- 8.4 引用和函数
- 8.4.1 引用作为函数参数
- 8.4.2 引用作为函数返回值
- 8.5 引用其他场景
- 8.5.1 常量引用
- 8.5.2 引用与数组
- 8.6 引用的本质
- 8.7 引用注意事项
- 8.7.1 避免返回局部变量引用
- 8.7.2 引用与指针的转换
- 8.8 引用综合案例
- 8.8.1 交换两个变量的值
- 8.8.2 返回数组元素的引用
8.1 引用的概念
8.1.1 什么是引用
在 C++ 中,引用 是一种别名机制,它为已存在的变量提供了一个新的名称。引用与指针类似,但更安全且易于使用。
引用是一个变量的别名,它必须在声明时初始化,并且一旦绑定到一个变量后,就不能再绑定到其他变量。
8.1.2 引用的声明
作用: 给变量起别名
数据类型 &引用名 = 变量名;
数据类型:引用绑定的变量的类型。&:表示这是一个引用。引用名:引用的名称。变量名:引用绑定的变量。
示例
void test1() {int a = 10;int &b = a; // b 是 a 的引用cout << "a = " << a << endl;cout << "b = " << b << endl;b = 100; //修改 b 等同于修改 acout << "a = " << a << endl;cout << "b = " << b << endl;
}int main() {test1();return 0;
}// a = 10
// b = 10
// a = 100
// b = 100
8.2 引用的特性
8.2.1 引用必须初始化
引用在声明时必须绑定到一个变量,否则会编译错误。
int num = 10;
int &ref = num; // 正确
int &ref2; // 错误:引用必须初始化
8.2.2 引用不能重新绑定
引用一旦绑定到一个变量后,就不能再绑定到其他变量。
int num1 = 10, num2 = 20;
int &ref = num1;
ref = num2; // 这是赋值操作,不是重新绑定
8.2.3 引用访问数据
通过引用可以访问和修改原变量的值。
int num = 10;
int &ref = num;
ref = 20; // 修改 ref 的值
cout << num; // 输出 20
8.3 引用与指针
| 特性 | 引用 | 指针 |
|---|---|---|
| 语法 | 类型& 引用名;比如 int& ref | 数据类型 * 变量名;比如 int* ref |
| 初始化 | 必须初始化 | 可以不初始化 |
| 重新绑定 | 不能重新绑定 | 可以重新指向其他变量 |
| 空值 | 不能为空 | 可以为 nullptr |
| 内存占用 | 不占用额外内存 | 占用额外内存(存储地址) |
| 语法 | 更简洁(直接使用变量名) | 需要解引用(* 操作符) |
8.4 引用和函数
8.4.1 引用作为函数参数
函数可以返回引用,但必须确保返回的引用指向的变量在函数调用结束后仍然有效。示例
void increment(int& num) {num++;
}int main() {int a = 10;increment(a); // 传递引用std::cout << a; // 输出 11return 0;
}
8.4.2 引用作为函数返回值
函数返回值 引用可以作为函数的返回值,但必须确保返回的引用指向有效的内存。
int& getMax(int& a, int& b) {return (a > b) ? a : b;
}int main() {int x = 10, y = 20;cout << "y = " << getMax(x,y) << endl; // 输出 20getMax(x, y) = 30; // 修改较大的值cout << "y = " << y << endl; // 输出 30return 0;
}
8.5 引用其他场景
8.5.1 常量引用
作用: 常量引用(const 引用)用于防止通过引用修改原变量,同时避免拷贝开销。
在函数形参列表中,可以加const修饰形参,防止形参改变实参
示例:
//引用使用的场景,通常用来修饰形参
void showValue(const int & v) {//v += 10; //常量不能做新的赋值。会直接编译报错cout << v << endl;
}void test() {//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);
}int main() {test();return 0;
}
8.5.2 引用与数组
引用可以绑定到数组,但语法较为特殊。示例
#include <iostream>
using namespace std;int main() {int arr[3] = {10, 20, 30};int (&ref)[3] = arr; // ref 是数组 arr 的引用for (int i = 0; i < 3; i++) {cout << ref[i] << " ";}return 0;
}
输出:
10 20 30
8.6 引用的本质
本质:引用的本质在c++内部实现是一个指针常量.
讲解示例:
//发现是引用,转换为 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;
}
结论:C++推荐用引用技术,因为语法方便,引用本质是指针常量,但是所有的指针操作编译器都帮我们做了。
8.7 引用注意事项
8.7.1 避免返回局部变量引用
避免返回局部变量的引用:局部变量在函数结束后会被销毁,返回其引用会导致未定义行为。
int& badFunction() {int a = 10;return a; // 错误:返回局部变量的引用
}
8.7.2 引用与指针的转换
引用与指针的转换:引用本质上是一个常量指针,但语法更简洁。
int a = 10;
int& ref = a;
int* ptr = &a;
// ref 和 *ptr 是等价的
8.8 引用综合案例
8.8.1 交换两个变量的值
void swap(int& a, int& b) {int temp = a;a = b;b = temp;
}int main() {int x = 10, y = 20;swap(x, y); // 传递引用std::cout << x << " " << y; // 输出 20 10return 0;
}
8.8.2 返回数组元素的引用
int& getElement(int arr[], int index) {return arr[index];
}int main() {int arr[] = {1, 2, 3, 4, 5};getElement(arr, 2) = 10; // 修改数组元素std::cout << arr[2]; // 输出 10return 0;
}
- 引用是变量的别名,必须在声明时初始化。
- 引用常用于函数参数传递、返回值优化等场景。
- 常量引用可以避免拷贝开销,同时防止修改原变量。
- 引用比指针更安全、更简洁,但不能重新绑定或为空。
通过合理使用引用,可以提高代码的效率和可读性,同时避免不必要的拷贝和内存管理问题。
