指针解剖学:穿透C/C++内存操作的核心密码与避坑指南

embedded/2025/2/28 11:05:48/

一、指针的本质与内存模型

指针是C/C++的核心特性,本质是内存地址的变量化表示。每个变量在内存中占据连续的字节空间,地址是内存单元的唯一编号(如0x0028FF40)。指针变量存储的是目标数据的首地址,通过地址间接操作数据。

内存模型示例:

int num = 97;      // 假设分配在地址0x0028FF40
int* p = #     // p存储0x0028FF40,*p解引用得到97
  • 步长:指针类型决定地址增减的步长(如int*步长为4字节,char*为1字节)。

二、指针的声明与操作

  1. 声明与初始化

    int* p;          // 声明int型指针
    int a = 10;
    p = &a;         // p指向a的地址
    int* q = NULL;  // 空指针,避免野指针问题
    
  2. 核心操作符

    • &:取地址符,获取变量内存地址(如&a)。
    • *:解引用符,访问指针指向的值(如*p = 20修改a的值)。
  3. 指针运算

    • 算术运算:p++使指针移动到下一个元素地址(步长由类型决定)。
    • 关系运算:比较指针地址大小(需指向同一数组)。

三、多级指针与复杂类型

  1. 二级指针
    指向指针指针,用于动态内存管理和函数参数传递:

    int pp = &p;  // pp存储p的地址
    pp = 30;      // 修改a的值为30
    
  2. 指针与数组

    • 数组名是首元素地址的常量指针(如int arr; int* p = arr;)。
    • 指针数组 vs. 数组指针
      int* arr;    // 数组元素为int指针
      int (*pArr); // 指向含5个int元素的数组的指针
      
  3. 函数指针
    指向函数的指针,用于回调机制:

    void (*funcPtr)(int) = &myFunction;  // 声明并赋值
    funcPtr(10);                         // 调用函数
    
  4. 函数指针

    • 本质是函数
    • 就是返回是指针的函数,即返回值是指针,是一个地址
    • 作用代码简洁、一定程度上节约内存
//三种写法都可以
int *fun(int x,int y);
int * fun(int x,int y)int* fun(int x,int y);

四、指针与动态内存管理

  1. 动态分配

    • C:malloc/calloc分配堆内存,需手动释放(free)。
    • C++:new/delete支持类型安全:
      int* arr = new int;  // 动态数组
      delete[] arr;            // 释放内存
      
  2. 智能指针(C++)

    • unique_ptr:独占所有权,禁止拷贝。
    • shared_ptr:引用计数,自动释放内存。

五、高级应用与注意事项

  1. 常量指针 vs. 指针常量

    const int* p1;    // 指向常量的指针(值不可改)
    int* const p2;    // 指针常量(地址不可改)
    
  2. 内存安全

    • 指针:未初始化或已释放的指针(需置为NULL)。
    • 内存泄漏:忘记释放动态内存(推荐使用RAII机制)。
  3. 与引用的区别
    引用是别名(编译期优化),指针是实体变量,支持运算和多级间接访问。


六、典型应用场景

  1. 数据结构:链表、树的节点链接。
  2. 函数参数:传递大型结构体避免拷贝。
  3. 系统编程:直接操作硬件寄存器或内存映射。

总结

指针是C/C++高效性和灵活性的核心,但也带来内存管理的复杂性。理解其底层机制(地址、步长、类型)和现代实践(智能指针、RAII)是掌握关键。建议结合调试工具(如Valgrind)验证内存操作安全性。

demo

#include <iostream>
using namespace std;// 定义结构体用于示例 
struct Student {int age;string name;
};int main() {// 1. 基础变量指针 int a = 10;int* p1 = &a;*p1 = 20;cout << "基础指针: " << a << endl; // 输出 20 [7]()// 2. 空指针与野指针 int* p2 = nullptr; // 安全空指针 // int* p3;        // 未初始化野指针(注释避免运行时崩溃)// 3. 数组指针操作 int arr[] = {1,2,3,4,5};int* p4 = arr;cout << "数组指针: " << *(p4 + 2) << endl; // 输出 3 [3]()// 4. 字符串指针 const char* str = "Hello";cout << "字符串指针: " << str[1]  << endl; // 输出 'e' [6]()// 5. 结构体指针 Student s = {20, "Tom"};Student* p5 = &s;cout << "结构体指针: " << p5->name << endl; // 输出 Tom [5]()// 6. 动态内存分配 int* p6 = new int(100);cout << "动态内存: " << *p6 << endl;delete p6; // 必须释放 [7]()// 7. 多维数组指针 int matrix[2][3] = {{1,2,3}, {4,5,6}};int (*p7)[3]  = matrix;cout << "多维数组: " << p7[1][2] << endl; // 输出 6 [3]()// 8. 函数指针 int (*funcPtr)(int, int) = [](int x, int y) { return x + y; };cout << "函数指针: " << funcPtr(3,5) << endl; // 输出 8 [6]()return 0;
}

http://www.ppmy.cn/embedded/167786.html

相关文章

【嵌入式Linux应用开发基础】网络编程(4):UDP协议

目录 一、UDP 协议概述 二、UDP 协议特点 三、UDP协议的字段格式 四、UDP协议的数据传输过程 五、嵌入式UDP编程核心API 六、UDP 在嵌入式 Linux 中的编程实现 6.1 UDP 服务器代码示例 6.2 UDP 客户端代码示例 七、UDP 协议的应用场景 八、UDP 协议的优缺点 8.1 优点…

【python随手记】——读取文本文件内容转换为json格式

文章目录 前言一、TXT文件转换为JSON数组1.txt文件内容2.python代码3.输出结果 二、TXT文件转换为JSON对象1.txt文件2.python代码3.输出结果 前言 场景&#xff1a;用于读取包含空格分隔数据的TXT文件&#xff0c;并将其转换为结构化JSON文件 一、TXT文件转换为JSON数组 1.tx…

AcWing 蓝桥杯集训·每日一题2025·密接牛追踪2

密接牛追踪2 农夫约翰有 N 头奶牛排成一排&#xff0c;从左到右依次编号为 1∼N。 不幸的是&#xff0c;有一种传染病正在蔓延。 最开始时&#xff0c;只有一部分奶牛受到感染。 每经过一个晚上&#xff0c;受感染的牛就会将病毒传染给它左右两侧的牛&#xff08;如果有的话…

(Qt) QThread 之 moveToThread

文章目录 &#x1f9f5;前言&#x1f9f5;QObject::moveToThread&#x1f5d2;️Code&#x1f5d2;️moveToThread 的基础使用&#x1f5d2;️注意点 &#x1f9f5;QThreadPool&#x1f5d2;️Code&#x1f5d2;️QThreadPool & QRunnable&#x1f5d2;️源码&#xff08;接…

【全栈开发】从0开始搭建一个图书管理系统【一】框架搭建

【全栈开发】从0开始搭建一个图书管理系统【一】框架搭建 前言 现在流行降本增笑&#xff0c;也就是不但每个人都要有事干不能闲着&#xff0c;更重要的是每个人都要通过报功的方式做到平日的各项工作异常饱和&#xff0c;实现1.5人的支出干2人的活计。单纯的数据库开发【肤浅…

全面解析:如何查找电脑的局域网与公网IP地址‌

在数字化时代&#xff0c;IP地址作为网络设备的唯一标识&#xff0c;对于网络连接、远程访问、网络诊断等方面都至关重要。无论是出于工作需要&#xff0c;还是解决网络问题&#xff0c;了解怎么查找电脑的IP地址都是一项必备技能。本文将详细介绍几种常见的方法&#xff0c;帮…

Vue nextTick原理回顾

nextTick就是将异步函数放在下一次实践循环的微任务队列中执行 实现原理比较简单&#xff0c;极简版本&#xff1a; function myNextTick(cb){let p;pPromise.resolve().then(cb)return cb?p:Promise.resolve() }复杂版本&#xff0c;考虑异步函数入队、执行锁、兼容处理 l…

Ubuntu 20.04 安装 Node.js 20.x、npm、cnpm 和 pnpm 完整指南

&#x1f310; Ubuntu 20.04 安装 Node.js 20.x、npm、cnpm 和 pnpm 完整指南 &#x1f680; 在本文中&#xff0c;我们将介绍如何在 Ubuntu 20.04 上安装 Node.js 20.x&#xff0c;以及如何安装 npm、cnpm 和 pnpm 来提高开发效率 ⚡。 1️⃣ 安装 Node.js 20.x 为了确保使用…