指针的引用

C++中要理解「指针的引用」,我们需要先拆解两个基础概念:指针引用,再看它们结合后的作用 —— 核心是「通过引用操作指针本身」。

一、先明确两个基础概念

1. 指针(T*
  • 本质:一个变量,存储的是另一个变量的「内存地址」。
  • 用途:通过地址间接访问 / 修改目标变量。
  • 示例:
    int a = 10;
    int* p = &a;  // p是指针,存储a的地址
    *p = 20;      // 通过指针修改a的值(a变成20)
    
2. 引用(T&
  • 本质:目标变量的「别名」,不是新变量,和目标变量共用同一块内存。
  • 用途:直接操作目标变量(比指针更简洁、安全)。
  • 规则:必须初始化(绑定一个变量),一旦绑定不能改绑。
  • 示例:
  • int a = 10;
    int& ref = a;  // ref是a的别名,和a同内存
    ref = 20;      // 直接修改a的值(a变成20)
    

二、指针的引用(T*&

定义:

「指针的引用」是 指针变量的别名—— 它不是指向变量的引用,而是指向「指针本身」的引用。语法:类型*& 引用名 = 指针变量名;*& 连写,明确是 “指针的引用”)

核心作用:

通过引用直接操作「指针变量本身」(比如修改指针的指向、修改指针存储的地址),而不是通过指针操作目标变量。这和普通指针参数(T*)的区别是:普通指针参数传递的是指针的「拷贝」,而指针的引用传递的是指针的「别名」,修改会直接作用于原指针。

三、为什么需要指针的引用?

核心优势是:要通过函数直接操作主函数中的指针(或其指向的数组),避免拷贝。

我们用对比来理解:假设要写排序函数,有两种参数传递方式:

方式 1:普通指针参数(double* arr
  • 传递的是指针的「拷贝」:函数内部的 arr 是主函数 arr 的副本,两者存储的地址相同(所以能通过 arr[j] 访问原数组),但指针本身是两个独立变量
  • 局限:函数内部无法修改主函数中指针的「指向」(比如让主函数的 arr 指向新数组),只能修改指针指向的「目标数据」(数组元素)。
  • 示例:

    // 普通指针参数:只能修改数组元素,不能修改指针本身
    void sort1(double* arr, int n) {
        arr = new double[5];  // 修改的是拷贝指针的指向,主函数的arr不受影响
        // 排序逻辑...
    }
    
    int main() {
        double* arr = new double[3]{1.1, 2.2, 3.3};
        sort1(arr, 3);  // 传递的是arr的拷贝
        delete[] arr;   // 主函数的arr仍指向原数组,正常释放
    }
    
方式 2:指针的引用参数(double*& arr
  • 传递的是指针的「别名」:函数内部的 arr 和主函数的 arr 是同一个指针变量,修改会直接作用于主函数的指针。
  • 优势:既可以通过 arr[j] 修改数组元素(和普通指针一样),也可以修改指针本身(比如让主函数的 arr 指向新地址)
  • 示例:
  • // 指针的引用参数:直接操作主函数的指针
    void sortDesc(double*& arr, int n) {
        // 冒泡排序:修改的是arr指向的数组元素(主函数的数组会同步变化)
        for (int i = 0; i < n-1; i++) {
            for (int j = 0; j < n-1-i; j++) {
                if (arr[j] < arr[j+1]) {
                    swap(arr[j], arr[j+1]);  // 直接修改原数组元素
                }
            }
        }
    }
    
    int main() {
        double* arr = new double[5]{3.2, 5.4, 6.12, 2.51, 4.23};
        sortDesc(arr, 5);  // 传递arr的引用(别名)
        // 主函数的arr指向的数组已被排序,直接输出即可
    }
    

四、指针引用的关键应用场景

场景 1:修改指针的指向(主函数中指针指向新地址)

#include <iostream>
using namespace std;

// 指针的引用:修改主函数中指针的指向
void changePtr(double*& ptr) {
    static double b = 99.9;  // 静态变量,地址固定
    ptr = &b;  // 修改指针的指向(主函数的ptr会同步指向b)
}

int main() {
    double a = 10.5;
    double* p = &a;  // 初始:p指向a
    cout << "修改前:*p = " << *p << endl;  // 输出10.5

    changePtr(p);  // 传递p的引用(别名)
    cout << "修改后:*p = " << *p << endl;  // 输出99.9(p已指向b)

    return 0;
}
场景 2:避免指针拷贝(提升效率)

当指针指向的是大数组 / 大对象时,传递指针的引用无需拷贝指针(虽然指针本身占用内存小,但逻辑上更直接),且能确保操作的是原指针。

五、常见误区(避坑!)

  1. 语法误区T*& 不能写成 T&*(语法错误)。

    • 原因:C++ 运算符优先级中,&(引用)比 *(指针)低,T&* 会被解析为「指向引用的指针」,但引用不是变量,没有地址,所以不允许。
  2. 用途误区不要用指针的引用 “多此一举”。

    • 若只需通过指针修改「目标变量 / 数组元素」,普通指针(T*)足够;
    • 若需要修改「指针本身」(比如改变指针指向、给指针重新分配内存),才需要指针的引用(T*&)。
  3. 和 “指向引用的指针” 区分

    • 指针的引用(T*&):合法,是指针的别名;
    • 指向引用的指针(T&*):非法,引用无地址,无法被指针指向。

总结

类型语法核心作用适用场景
普通指针T*操作指针指向的「目标变量」间接访问 / 修改目标数据
指针的引用T*&操作「指针本身」(别名)修改指针指向、避免指针拷贝
普通引用T&操作「变量本身」(别名)直接访问 / 修改变量(替代指针)

简单记:

  • 想改「目标数据」→ 用普通指针(T*)或普通引用(T&);
  • 想改「指针本身」→ 用指针的引用(T*&)。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值