C++ 学习笔记(3):引用和指针

前言

前几天问 GPT 问的,单独拎出来当作笔记的一个补充吧。

指针的基本概念

指针(Pointer) 是一个变量,它存储的是另一个变量的内存地址。在 C++ 中,定义一个指针变量时使用 * 符号,这个符号并不是表示解引用,而是表示这个变量是一个指针变量,指向某种类型的数据。

例子

int a = 5;
int* p = &a;  // p 是一个指向 a 的指针,&a 获取 a 的地址

在上面的例子中,&a 表示获取 a 的内存地址,而 int* p 表示定义一个指向 int 类型的指针变量 p*p 表示解引用,访问指针 p 指向的内存位置中的数据。

解引用的概念

解引用(Dereferencing) 是指通过指针访问它指向的内存地址中的内容。当你使用 *p 时,你是在访问指针 p 存储的地址所指向的数据,而不是地址本身。

例子

int a = 5;
int* p = &a;  // p 存储 a 的地址
cout << *p;    // 解引用 p,输出 5,因为 p 指向 a

重要概念: *p 代表解引用,访问的是指针 p 所指向内存位置中的数据,而不是 p 本身。也就是说,*p 是访问 a 的值(即 5),而 p 只是存储了 a 的地址。

引用与指针的区别

引用(Reference) 只是某个对象的别名,通过引用,你直接操作原始对象的数据。引用变量不存储内存地址,只是对已有对象的别名,不能为 null 或空指针。

例子

int a = 5;
int& ref = a;  // ref 是 a 的引用
ref = 10;      // 修改 ref 的值,a 变为 10
cout << a;     // 输出 10,a 被修改了

在这个例子中,ref 直接代表 a修改 ref 就等于修改 a。没有像指针那样通过解引用去访问,引用的操作更直接、简洁。

常见误解:*p = &x*p 的使用

我前面提到了一个问题,就是:为什么 *p = &x 不成立,而 *p 作为解引用操作并没有做到“放地址”。这实际是理解上的一个小误区。

关键点

定义指针时,*p 是用来声明指针的类型,它告诉编译器 p 是一个指向某类型(如 int)的指针。而 &x 是取地址操作,表示你要拿到 x 变量的内存地址。

*p = &x 其实是错误的,因为 *p 不是存储地址的地方,它应该存储的是,而不是一个地址。正确的做法是:

  int x = 10;
  int* p = &x;   // p 存储的是 x 的地址
  *p = 20;        // 解引用 p,把 x 的值改成 20
  cout << x;      // 输出 20,x 的值被修改了

正确理解: 当你用 *p 进行解引用时,它实际上是指向 p 所指向的内存位置的内容。所以 *p 用于访问指针指向的对象的值,而不是用来放地址的

引用与指针的比较

特性 引用(Reference) 指针(Pointer)
定义时初始化 必须在定义时初始化,一旦初始化后无法改变。 可以初始化为 nullptr,并且可以随时改变指向的对象。
存储内容 存储对象的别名,没有独立的内存地址。 存储的是一个内存地址,指向某个对象。
是否为空 不可以为空,引用必须绑定到一个对象。 可以为空(nullptr),也可以指向不同的对象。
访问方式 直接使用引用变量名即可访问原始对象。 使用 * 操作符解引用来访问指针所指向的内容。
是否可以改变 一旦绑定,引用无法指向其他对象。 可以改变指针指向的对象,甚至指向 nullptr
适用场景 适用于不需要重新绑定的对象,通常用于修改对象的值。 适用于需要灵活指向不同对象、动态内存分配和处理链表等。

例子:引用和指针的操作对比

#include <iostream>
using namespace std;

void byReference(int& ref) {
    ref = 10;  // 通过引用修改原始值
}

void byPointer(int* p) {
    *p = 20;  // 通过指针解引用修改原始值
}

int main() {
    int a = 5;
    int b = 15;
    
    byReference(a);  // a 通过引用传递给函数,a 变为 10
    byPointer(&b);    // b 通过指针传递给函数,b 变为 20

    cout << "a: " << a << endl;  // 输出 a: 10
    cout << "b: " << b << endl;  // 输出 b: 20
    
    return 0;
}

引用:直接作为别名操作数据,语法简单且无需解引用。指针:存储的是地址,需要通过解引用来访问指向的数据,使用时更灵活。

常见的使用场景

引用 常用于函数参数传递(避免传值开销),或者需要直接修改原始对象的场景。指针 常用于动态内存分配(newdelete)、数据结构(链表、树)、以及需要操作多个对象或空指针的场景。

总结

指针 是一个变量,它存储了某个对象的内存地址,并且通过 * 来解引用,访问或修改指向的对象的内容。引用 是某个对象的别名,它直接代表对象本身,不需要解引用操作,操作简洁。在 定义指针时*p 只是用来告诉编译器 p 是一个指针类型变量,而 解引用 是通过 *p 访问指针指向的内容。

这篇结束后打算直接刷题了,发现一点一点学根本没那时间我服了。

posted @   AurLemon  阅读(53)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· winform 绘制太阳,地球,月球 运作规律
· AI与.NET技术实操系列(五):向量存储与相似性搜索在 .NET 中的实现
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 上周热点回顾(3.3-3.9)
点击右上角即可分享
微信分享提示