C++ 指针:初学者指南

你好,未来的程序员们!今天,我们将踏上一段激动人心的旅程,进入 C++ 指针的世界。如果你之前从未编写过一行代码,也不用担心——我会成为你的友好向导,我们将一步一步地探索这个主题。那么,让我们跳进去吧!

C++ Pointers

什么是指针?

想象你在一个巨大的图书馆里。每本书都有它在书架上的独特位置,对吧?在计算机的世界里,内存就像这个图书馆,而指针就像小纸条,告诉我们如何准确地找到特定信息的位置。

在 C++ 中,指针是一个存储另一个变量内存地址的变量。这就好比拥有一张直接指向我们数据存储位置的藏宝图!

让我们来看一个简单的例子:

int age = 25;          // 一个普通的整型变量
int* ptr_age = &age;   // 一个存储 'age' 地址的指针变量

在这段代码中:

  • age 是一个存储值 25 的普通整型变量。
  • ptr_age 是一个指针变量。* 告诉我们它是一个指针。
  • &age 给我们 age 变量的内存地址。

所以,ptr_age 现在持有 age 在内存中存储的地址。酷吧?

在 C++ 中使用指针

既然我们知道了什么是指针,那么让我们来看看如何使用它们。使用指针主要有两种操作:

  1. 获取一个变量的地址(使用 &
  2. 访问一个地址的值(使用 *

这里有一个更全面的例子:

#include <iostream>
using namespace std;

int main() {
int cookie_count = 5;
int* ptr_cookies = &cookie_count;

cout << "饼干数量: " << cookie_count << endl;
cout << "cookie_count 的地址: " << ptr_cookies << endl;
cout << "地址的值: " << *ptr_cookies << endl;

*ptr_cookies = 10;  // 使用指针改变值
cout << "新的饼干数量: " << cookie_count << endl;

return 0;
}

让我们分解一下:

  1. 我们创建了一个整型变量 cookie_count 并将其设置为 5。
  2. 我们创建了一个指针 ptr_cookies,它存储 cookie_count 的地址。
  3. 我们直接打印 cookie_count 的值。
  4. 我们打印存储在 ptr_cookies 中的地址(即 cookie_count 的地址)。
  5. 我们使用 *ptr_cookies 来访问存储在 ptr_cookies 地址中的值。
  6. 我们使用 *ptr_cookies = 10 来改变地址中的值。
  7. 我们再次打印 cookie_count 以查看变化。

当你运行这个程序时,你会看到通过指针改变值也会改变原始变量。这就像魔法一样,但实际上这只是指针的工作原理!

C++ 指针:高级概念

当我们对指针越来越熟悉时,让我们探索一些高级概念。

指针和数组

在 C++ 中,数组和指针紧密相关。实际上,数组的名称本质上是指向其第一个元素的指针。让我们看一个例子:

int numbers[] = {1, 2, 3, 4, 5};
int* ptr = numbers;  // ptr 现在指向 numbers 的第一个元素

cout << "第一个元素: " << *ptr << endl;
cout << "第二个元素: " << *(ptr + 1) << endl;
cout << "第三个元素: " << *(ptr + 2) << endl;

在这里,ptr 指向 numbers 数组的第一个元素。我们可以通过增加指针来访问其他元素。

动态内存分配

指针的一个非常强大的用途是在动态内存分配中。这允许我们创建在编译时不知道大小变量的数组和变量。

int* dynamic_array = new int[5];  // 为 5 个整数分配内存

for(int i = 0; i < 5; i++) {
dynamic_array[i] = i * 10;
}

for(int i = 0; i < 5; i++) {
cout << dynamic_array[i] << " ";
}

delete[] dynamic_array;  // 使用完毕后不要忘记释放内存!

在这个例子中,我们使用 new 来分配一个整型数组的内存。我们可以像使用普通数组一样使用这个数组。当我们完成后,我们使用 delete[] 来释放内存。

指向指针的指针

是的,我们可以有指向指针的指针!这个概念在许多高级编程场景中非常有用。

int value = 42;
int* ptr1 = &value;
int** ptr2 = &ptr1;

cout << "值: " << **ptr2 << endl;  // 这将打印 42

在这里,ptr2 是一个指向指针的指针。我们需要使用 ** 来访问它最终指向的值。

常见的指针操作

让我们总结一些在下面方便的表格中的常见指针操作:

操作 语法 描述
声明 int* ptr; 声明一个指向整数的指针
赋值 ptr = &var; 将变量 var 的地址赋给 ptr
解引用 *ptr 访问 ptr 指向的值
自增 ptr++ 将指针移动到下一个内存位置
自减 ptr-- 将指针移动到上一个内存位置
空赋值 ptr = nullptr; 将指针赋值为空

记住,能力越大,责任越大。指针很强大,但如果不小心使用,也可能导致错误。始终初始化你的指针,并且注意内存管理。

总之,指针一开始可能看起来有点复杂,但通过练习,它们会成为你 C++ 编程工具箱中宝贵的工具。它们允许高效的内存管理,使强大的数据结构成为可能,并且是许多高级 C++ 概念的基础。

继续练习,保持好奇心,快乐编码!

Credits: Image by storyset