高考数学97分,我的“数学直觉“比140分更好用:指针:内存的门牌号系统
目录一.序言二.数学直觉三.核心概念1.基础核心概念1. 1.指针的本质1.2. 指针的两大核心操作1.3. 指针的类型2.进阶核心概念2.1. 指针与数组的关系2.2. 指针的运算2. 3. 多级指针3.应用核心概念3.1. 指针作为函数参数3.2. 动态内存分配3.3. 函数指针4.安全核心概念4.1. 空指针NULL4.2. 野指针与悬空指针4.3. 内存泄漏四.代码实现1. 指针基础操作2. 数组与指针3. 指针作为函数参数4. 动态内存分配5. 函数指针6. 多级指针五.最后总结一.序言大家好我是你们的小洛。上一章我们讲了模块化封装的函数这一节我们首先要知道的一个就是系统通过管理内存来实现对变量的操作而变量只是内存的代言人。既然变量只是内存的代言人那我们如何绕过这个代言人直接拿到内存的门牌号来操作呢二.数学直觉首先我们要理解系统再找变量的核心就是地址系统识别不了变量名他只能识别地址变量名就像别人给你取的外号所以通过变量名映射地址系统通过地址来进行操作这个量。如果我们把我们自己当做是一个系统把学校的教学楼当做是一个程序那么每一间教室就是内存空间每一个门牌号就是这个内存的编号指针就是这个这个编号我们在用到一个东西时我们可以直接根据门牌号指针找这个教室去这个教室找东西我们也可以用指针变量先找到这间教室的门牌号指针再去根据门牌号找这个教室。三.核心概念1.基础核心概念1. 1.指针的本质指针就是内存地址指针变量就是存储地址的变量。1.2. 指针的两大核心操作取地址 获取变量的内存地址取值* 通过地址访问或修改数据与互为逆运算*p得到的是p指向的值而非p本身1.3. 指针的类型指针类型决定了解引用时访问的内存大小int* 访问4字节 char* 访问1字节2.进阶核心概念2.1. 指针与数组的关系数组名在表达式中通常退化为指向首元素的指针但sizeof(arr)时仍是数组类型arr[i] 等价于 *(arr i)2.2. 指针的运算指针加减根据类型大小偏移地址指针比较比较地址的大小关系2. 3. 多级指针指向指针的指针 int** p 用于间接修改指针本身的值3.应用核心概念3.1. 指针作为函数参数实现传引用效果修改外部变量避免大数据的复制提高效率3.2. 动态内存分配malloc 分配堆内存返回指针通过指针管理动态内存的生命周期3.3. 函数指针指向函数的指针存储函数的入口地址实现回调函数和动态调用4.安全核心概念4.1. 空指针NULL不指向任何有效内存的指针使用前应检查避免程序崩溃4.2. 野指针与悬空指针野指针指向未分配或已释放的内存悬空指针原指向的内存已释放但指针仍保存旧地址4.3. 内存泄漏动态分配的内存未释放导致内存资源浪费四.代码实现1. 指针基础操作#include stdio.h int main() { int a 10; int* p a; // 取地址 printf(a的值: %d\n, a); printf(a的地址: %p\n, a); printf(p的值: %p\n, p); printf(*p的值: %d\n, *p); // 解引用 *p 20; // 通过指针修改a的值 printf(修改后a的值: %d\n, a); return 0; } //a的值: 10 //a的地址: 0x7ffee6b1e76c //p的值: 0x7ffee6b1e76c //*p的值: 10 //修改后a的值: 202. 数组与指针#include stdio.h int main() { int arr[5] {1, 2, 3, 4, 5}; int* p arr; // 数组名是首元素地址 printf(数组元素: ); for(int i 0; i 5; i) { printf(%d , *(p i)); // 指针偏移访问 } printf(\n); printf(数组元素: ); for(int i 0; i 5; i) { printf(%d , p[i]); // 指针下标访问 } printf(\n); return 0; } //数组元素: 1 2 3 4 5 //数组元素: 1 2 3 4 53. 指针作为函数参数#include stdio.h // 通过指针修改外部变量 void swap(int* a, int* b) { int temp *a; *a *b; *b temp; } int main() { int x 10, y 20; printf(交换前: x%d, y%d\n, x, y); swap(x, y); printf(交换后: x%d, y%d\n, x, y); return 0; } //交换前: x10, y20 //交换后: x20, y104. 动态内存分配#include stdio.h #include stdlib.h int main() { int n; printf(请输入数组大小: ); scanf(%d, n); // 动态分配内存 int* arr (int*)malloc(n * sizeof(int)); if(arr NULL) { printf(内存分配失败\n); return 1; } // 填充数据 for(int i 0; i n; i) { arr[i] i 1; } // 输出数据 printf(动态数组: ); for(int i 0; i n; i) { printf(%d , arr[i]); } printf(\n); // 释放内存 free(arr); return 0; } //请输入数组大小: 5 //动态数组: 1 2 3 4 55. 函数指针#include stdio.h // 加法函数 int add(int a, int b) { return a b; } // 乘法函数 int multiply(int a, int b) { return a * b; } int main() { // 函数指针 int (*operation)(int, int); // 指向加法函数 operation add; printf(3 5 %d\n, operation(3, 5)); // 指向乘法函数 operation multiply; printf(3 * 5 %d\n, operation(3, 5)); return 0; } //3 5 8 //3 * 5 156. 多级指针#include stdio.h void modify_pointer(int** pp) { static int b 200; *pp b; // 修改指针p本身 } int main() { int a 100; int* p a; printf(修改前: *p %d\n, *p); modify_pointer(p); // 传递指针的地址 printf(修改后: *p %d\n, *p); return 0; } //修改前: *p 100 //修改后: *p 200五.最后总结总的来说指针就是这个内存的地址名指针变量就是用来存放指针的。通过指针直接操作内存就像直接修改游戏后台数据一样比通过变量操作更加灵活可以实现更多自定义功能实现常规操作难以达到的效果。下节预告自定义数据类型打包与复用
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2418690.html
如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!