langShift

指针和引用

在 C++ 中,指针和引用是允许直接内存操作和高效数据传递的基本概念。它们对于理解 C++ 如何管理内存以及与硬件交互至关重要,并且它们与 JavaScript 的内存模型有显著差异。

指针概念和语法

指针是一个存储另一个变量内存地址的变量。它“指向”内存中存储值的位置。指针功能强大,但需要仔细处理。

声明和初始化指针

  • int* ptr; // 声明一个指向整数的指针。
  • int* ptr = &variable; // 使用 variable 的地址初始化 ptr

解引用指针

  • *ptr // 访问存储在 ptr 中内存地址的值。
正在加载...

引用概念和语法

引用是现有变量的别名(另一个名称)。一旦引用被初始化为一个变量,它就不能被重新设置以引用另一个变量。引用通常用于通过引用将参数传递给函数。

声明和初始化引用

  • int& ref = variable; // 声明一个引用 ref 并将其绑定到 variable
正在加载...

指针算术运算

指针算术运算涉及对指针执行算术运算。它主要用于数组。

  • ptr + n:将指针向前移动 n 个元素(而不是 n 个字节)。
  • ptr - n:将指针向后移动 n 个元素。
  • ptr1 - ptr2:计算 ptr1ptr2 之间的元素数量。
正在加载...

函数指针

函数指针是指向函数内存地址的指针。它允许你间接调用函数、将函数作为参数传递或将它们存储在数据结构中。

正在加载...

指针和引用之间的差异

特性指针引用
初始化可以不初始化声明 (但危险)必须在声明时初始化
空值可以是 nullptr (或 NULL)不能为空
重新赋值可以重新赋值以指向不同的变量不能重新设置 (始终引用相同的变量)
内存地址存储内存地址是别名;不存储自己的地址 (概念上)
解引用需要 * 才能解引用不需要明确的解引用运算符 (直接使用)

常见指针错误

  • 悬空指针: 指向已释放内存的指针。
  • 野指针: 未初始化且指向任意内存位置的指针。
  • 空指针解引用: 尝试解引用 nullptr,导致程序崩溃。
  • 内存泄漏: 忘记 delete 动态分配的内存(模块 2 中已涵盖)。

与 JavaScript 引用的比较

JavaScript 没有 C++ 意义上的明确指针或引用。相反,持有对象(包括数组和函数)的 JavaScript 变量存储对这些对象的引用。这些引用由 JavaScript 引擎的垃圾回收器管理。

  • 无手动内存管理: 你不需要在 JavaScript 中 newdelete 对象;GC 会处理它。
  • 无指针算术运算: 你不能对 JavaScript 引用执行算术运算。
  • 引用可以重新赋值: 与 C++ 引用不同,JavaScript 引用可以重新赋值以指向不同的对象。

本质上,JavaScript 的对象引用在某种程度上类似于 C++ 指向对象的指针,但具有自动内存管理,并且无法执行指针算术运算或直接内存访问。


练习题:

  1. 解释 C++ 指针和 C++ 引用之间核心差异。何时会选择使用其中一个?
  2. 编写一个 C++ 函数,该函数接受一个整数指针作为参数,将其指向的值增加 5,然后打印新值。演示如何在 main 中调用此函数。
  3. 什么是悬空指针,以及如何在 C++ 中避免创建它?

项目构想:

  • 使用原始指针在 C++ 中实现一个简单的动态数组(类似于 std::vector)。你的实现应包括添加元素、移除元素、调整数组大小和按索引访问元素的函数。密切注意内存分配和释放,以防止内存泄漏和悬空指针。