指针和引用

介绍

在C++中,指针和引用是两种重要的概念,它们都用于间接访问变量,但它们的使用方式和特性有所不同。下面是对指针和引用的详细讲解:

指针(Pointer)

定义:指针是一个存储内存地址的变量,使用 * 声明指针类型,可以通过指针间接访问和修改变量的值。

声明:使用*符号来声明指针。

int* ptr; // ptr是一个指向int类型的指针

初始化:指针可以通过取地址运算符&来初始化:

int a = 10;  
int* ptr = &a; // ptr现在指向变量a的地址

解引用:使用*运算符可以访问指针所指向的值:

int value = *ptr; // value现在是10

指针的运算:指针可以进行算术运算,例如加减操作,通常用于数组的遍历。

空指针:指针可以被设置为nullptr,表示它不指向任何有效的内存地址:

int* ptr = nullptr;

引用(Reference)

定义:引用是某个变量的别名,使用 & 声明引用类型,必须在声明时初始化,一旦绑定,不能更改引用的对象。

声明:使用&符号来声明引用。例如:

int a = 10;  
int& ref = a; // ref是a的引用

使用:引用可以像普通变量一样使用:

ref = 20; // 这将改变a的值为20

引用的特性:

引用必须在声明时初始化。

引用不能为nullptr,也不能指向不同的变量。

引用通常用于函数参数和返回值,以避免复制开销。

指针与引用的比较

总结

指针和引用在C++中各有其用途。指针提供了更大的灵活性和控制,但也带来了更高的复杂性和潜在的错误(如悬空指针)。引用则提供了一种更安全和简洁的方式来处理变量,尤其是在函数参数传递时。理解这两者的区别和使用场景对于编写高效和安全的C++代码至关重要。

初学者入门可以看视频,简单讲解:https://www.bilibili.com/video/BV18exnehEeF/?spm_id_from=333.337.search-card.all.click&vd_source=cb02f779bd17a3aad9801e0c4464dfc9

指针和引用的关系

引用就是作用阉割(更安全)的指针(可以视为“type *const” 指针常量,所以引用必须上来就赋初值,不能设置为空),编译器不将引用视作对象,操作引用相当于操作引用指向的对象。也就从根本是杜绝了引用篡改内存的能力

进一步解释:

指针是一个变量,可以存储不同的地址(可以指向不同的内存)所以指针是可以修改内存的;引用是更安全的指针,它是类型*const,存储的地址不能改变(和第一次指向的内存锁死了)它其实是一个指针常量,杜绝了引用篡改内存的能力;

#include <iostream>


int main() {

    int i = 20;
    int& refI = i;
    int* const pi= &i;  // int& = int* cosnt  引用 = 指针常量

    std::cout << "refI: " << refI << ", *p: " << *pi << std::endl;

    return 0;
}

指针和引用的作用和区别

下面的思维导图总结的很好

野指针,悬挂指针,如何避免使用野指针和悬挂指针

野指针:野指针是指未初始化的指针

int* ptr;  // 未初始化的指针,这是一个野指针  
*ptr = 10; // 危险!可能导致程序崩溃

悬挂指针:悬挂指针是指原本指向的内存已经被释放或不再有效的指针

int* createDanglingPointer() {  
    int x = 10;  
    return &x;  // 返回局部变量的地址,函数结束后x将被销毁  
}  // x 被销毁后,返回的指针变成悬挂指针

如何避免野指针:指针定义时需要初始化

如何避免悬挂指针:delete后,指针置空

或者直接使用智能指针