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 等同于修改 a
    cout << "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; // 输出 11
    return 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; // 输出 20
    getMax(x, y) = 30; // 修改较大的值
    cout << "y = " << y << endl; // 输出 30
    return 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 10
    return 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];     // 输出 10
    return 0;
}
  • 引用是变量的别名,必须在声明时初始化。
  • 引用常用于函数参数传递、返回值优化等场景。
  • 常量引用可以避免拷贝开销,同时防止修改原变量。
  • 引用比指针更安全、更简洁,但不能重新绑定或为空。

通过合理使用引用,可以提高代码的效率和可读性,同时避免不必要的拷贝和内存管理问题。

本站提供的所有下载资源均来自互联网,仅提供学习交流使用,版权归原作者所有。如需商业使用,请联系原作者获得授权。 如您发现有涉嫌侵权的内容,请联系我们 邮箱:[email protected]