数据结构——指针

指针是 C/C++ 语言中最核心也最具特色的概念,可以把它理解为 C 语言的"灵魂"。掌握指针,是深入理解内存、数据结构等高级主题的关键。

🤔 什么是指针?

简单来说,指针就是内存地址

我们可以用一个生活中的例子来类比:

  • 内存 就像一栋巨大的宿舍楼。
  • 内存单元(字节) 就是楼里的每一个房间。
  • 地址 就是每个房间唯一的门牌号。
  • 变量 就是住在某个房间里的"人"或"物品"。
  • 指针 就是一个小本子,上面记录着某个变量所住房间的"门牌号"。

所以,指针变量就是一种特殊的变量,它不直接存储数据,而是专门用来存储另一个变量的内存地址。

🔑 两个核心符号:&*

理解指针,必须掌握两个操作符:

  1. 取地址符 &

    • 作用:获取一个变量在内存中的地址(门牌号)。
    • 示例&a 表示获取变量 a 的地址。
  2. 解引用符 *

    • 作用:通过指针中存储的地址,找到并访问该地址上存放的实际数据(根据门牌号找到房间里的人)。
    • 示例 :如果指针 p 存储了变量 a 的地址,那么 *p 就代表变量 a 本身。

特别注意 :在定义指针时,* 的作用是声明,表示"这是一个指针变量",而不是解引用。

💻 指针的基本使用

让我们通过一段代码来直观地感受一下:

c 复制代码
#include <stdio.h>

int main() {
    int a = 100;      // 定义一个整型变量 a,值为 100
    int *p = &a;      // 定义一个整型指针 p,并将 a 的地址赋给它

    printf("a 的值是: %d\n", a);     // 输出: 100
    printf("a 的地址是: %p\n", &a);  // 输出 a 的内存地址
    printf("p 的值是: %p\n", p);     // 输出 p 中存储的地址,和 &a 相同
    printf("*p 的值是: %d\n", *p);   // 输出: 100,通过地址访问 a 的值

    // 通过指针修改 a 的值
    *p = 200;
    printf("修改后,a 的值是: %d\n", a); // 输出: 200

    return 0;
}

这段代码清晰地展示了如何通过指针 p 来间接访问和修改变量 a 的值。

❓ 为什么指针要有类型?

你可能会问,既然指针存的都是地址(一个数字),为什么还要分 int*char*double* 呢?

这是因为指针的类型决定了它的两种关键行为:

  1. 解引用时,操作多少字节

    • char* 解引用时,只访问 1个字节 的数据。
    • int* 解引用时,会访问 4个字节 的数据(在大多数系统上)。
    • 这决定了指针如何"解释"它指向的内存内容。
  2. 指针运算时,移动的步长

    • 当你执行 p + 1 时,指针 p 并不是简单地将地址值加1。
    • char* 类型的指针加1,地址会向后移动 1个字节
    • int* 类型的指针加1,地址会向后移动 4个字节 ,刚好跳到下一个 int 类型数据的位置。
    • 这保证了指针能正确地遍历数组等数据结构。

⚠️ 两个重要概念:空指针与野指针

在使用指针时,必须警惕两种危险情况:

  • 空指针 (NULL Pointer)

    • 这是一个被明确初始化为 NULL (或 0) 的指针,表示它不指向任何有效的内存地址。使用空指针是一种良好的编程习惯,可以避免意外访问。
  • 野指针 (Wild Pointer)

    • 这是一个指向了"未知"或"已释放"内存的指针。它通常是因为指针在定义时没有初始化,或者指向的变量生命周期结束后,指针没有被置为 NULL。访问野指针会导致程序崩溃或产生不可预测的错误,是编程中的大忌。

🤝 指针与引用 (C++)

在 C++ 中,引用(&)是指针的一种更安全、更易用的替代方案。它们的核心区别如下:

特性 指针 (Pointer) 引用 (Reference)
本质 存储地址的变量 变量的别名
空值 可以为空 (nullptr) 不能为空,必须初始化
重新绑定 可以改变指向 绑定后不可改变
安全性 较低,易出现野指针 较高,无空引用风险

简单来说,引用更像是一个变量的"绰号",一旦确定就不能更改,并且这个"绰号"必须对应一个真实存在的变量。

相关推荐
MediaTea7 小时前
AI 术语通俗词典:C4.5 算法
人工智能·算法
Navigator_Z7 小时前
LeetCode //C - 1033. Moving Stones Until Consecutive
c语言·算法·leetcode
WBluuue7 小时前
数据结构与算法:莫队(一):普通莫队与带修莫队
c++·算法
风筝在晴天搁浅8 小时前
n个六面的骰子,扔一次之后和为k的概率是多少?
算法
MATLAB代码顾问9 小时前
Python实现蜂群算法优化TSP问题
开发语言·python·算法
代码飞天9 小时前
机器学习算法和函数整理——助力快速查阅
人工智能·算法·机器学习
jiushiapwojdap9 小时前
LU分解法求解线性方程组Matlab实现
数据结构·其他·算法·matlab
笨笨饿10 小时前
69_如何给自己手搓一个串口
linux·c语言·网络·单片机·嵌入式硬件·算法·个人开发
纽扣66710 小时前
【算法进阶之路】链表进阶:删除、合并、回文与排序全解析
数据结构·算法·链表
消失的旧时光-194310 小时前
统一并发模型:线程、Reactor、协程本质是一件事(从线程到协程 · 第6篇·终章)
java·python·算法