C++ 指针与链表可视化

从内存地址到动态数据结构

1. 什么是指针?

指针是一个变量,其值为另一个变量的内存地址。在 C++ 中,我们使用 `*` 声明指针,使用 `&` 获取地址。

0x7ffed1
int* p
0x7ffed2
→
0x7ffed2
int a
42
int a = 42;
int* p = &a; // p 存储了 a 的地址
cout << *p;  // 解引用:输出 42

2. 单链表 (Linked List)

链表是由一系列节点 (Node) 组成的。每个节点包含数据和指向下一个节点的指针。它是动态分配内存的典型应用。

struct Node {
    int data;
    Node* next;
};

// 插入逻辑
Node* newNode = new Node();
newNode->data = value;
newNode->next = nullptr;

3. 指针数组

指针数组是存储指针的数组。每个元素都是一个指针,指向相应的变量。

int arr[] = {10, 20, 30, 40, 50};
int* ptr = arr;  // ptr 指向 arr[0]
ptr++;          // ptr 现在指向 arr[1]
cout << *ptr;   // 输出: 20

4. 栈 (Stack)

栈是后进先出 (LIFO) 的数据结构。使用指针可以实现动态栈操作。

struct StackNode {
    int data;
    StackNode* next;
};

void push(StackNode*& top, int value) {
    StackNode* newNode = new StackNode();
    newNode->data = value;
    newNode->next = top;
    top = newNode;
}

5. 双向链表 (Doubly Linked List)

双向链表的每个节点有两个指针:一个指向前驱,一个指向后继。

struct DLLNode {
    int data;
    DLLNode* prev;
    DLLNode* next;
};

// 每个节点可以双向遍历
prev ← [data|prev|next] → next

6. 指针运算演示

指针可以进行算术运算,这在数组访问中特别有用。

0x1000
int arr[5]
{10,20,30,40,50}
→
0x1000
int* p
*p = 10
int arr[] = {10, 20, 30, 40, 50};
int* p = arr;
// p = 0x1000, *p = 10