网站开发pc版与手机版房产中介网站模板

张小明 2025/12/25 15:16:40
网站开发pc版与手机版,房产中介网站模板,企业网站开发研究现状,织梦cms如何做网站本文Gittee: 东华逐梦码为径#xff0c;万里探真路自长。 指针是 C 语言的灵魂#xff0c;也是初学者的 “拦路虎”。很多人觉得指针难#xff0c;核心是没搞懂 “地址” 和 “指针变量” 的本质关系。这篇文章会抛开复杂概念#xff0c;用生活案例 极简代码#x…本文Gittee: 东华逐梦码为径万里探真路自长。指针是 C 语言的灵魂也是初学者的 “拦路虎”。很多人觉得指针难核心是没搞懂 “地址” 和 “指针变量” 的本质关系。这篇文章会抛开复杂概念用生活案例 极简代码从底层逻辑到实战用法层层拆解让你彻底摸清指针的门道。一、先搞懂底层内存、地址和指针的本质要学指针先明白计算机是怎么管理内存的 ——指针的所有操作本质都是和 “内存地址” 打交道。电脑内存功能电脑内存就像 CPU 的 “专属工作台”—— 硬盘是存放所有资料的仓库而内存是 CPU 干活时临时摆资料、工具的桌面。核心功能程序运行前会从 “仓库”硬盘搬到 “工作台”内存方便 CPU 快速取用。工作台越大内存容量越大能同时摆下的程序、数据越多CPU 不用频繁跑仓库取东西干活效率更高。活儿干完程序关闭 / 关机工作台上的临时资料会清空下次用再重新从仓库调取。1.1 内存计算机的 “宿舍楼”计算机的内存就像一栋宿舍楼每间 “宿舍” 就是一个内存单元大小固定为 1 字节能存 8 个二进制位类似 8 人间宿舍。宿舍要编号才能快速找到人内存单元也需要编号这个编号就是地址。C 语言里地址还有个专属名字指针。核心结论内存单元的编号 地址 指针三者完全等价。1.2 地址是怎么来的硬件编址的底层逻辑地址不是凭空生成的是计算机硬件通过 “地址总线” 设计出来的32 位机器有 32 根地址总线每根线只有 0/1 两种状态有电 / 没电。32 根线能组合出 2³² 种状态每种状态对应一个地址所以 32 位系统最大支持 4GB 内存2³² 字节 4GB。64 位机器有 64 根地址总线支持的内存空间更大理论上 16EB。1.3 关键单位换算1Byte字节 8bit比特位 1KB 1024Byte 1MB 1024KB 1GB 1024MB 1TB 1024GB二、核心工具指针变量的定义与使用知道了地址的本质指针变量就好理解了 —— 它就是专门用来存 “地址” 的变量类似用小本本记宿舍门牌号。2.1 取地址操作符 拿到变量的 “门牌号”我们在第二讲第六节中讲过变量创建的本质变量创建的本质是对内存空间的申请忘了可以回去看看创建变量时计算机会给变量分配内存空间比如 int 变量占 4 字节 操作符能取出变量的地址即首字节地址。代码示例#include stdio.h int main() { int a 10; // 申请4字节内存存10 printf(a的地址%p\n, a); // %p是地址的格式化输出符 return 0; }运行结果a的地址006FFD70随机值、X86环境实际上变量 a 占 4 字节地址分别是 006FFD70、006FFD71、006FFD72、006FFD73a 取出的是最小的首地址。2.2 指针变量定义存地址的 “小本本”指针变量的定义格式数据类型 * 变量名其中*表示这是指针变量。前面的 “数据类型” 表示指针指向的变量类型关键后面会讲。代码示例#include stdio.h int main() { int a 10; int *pa a; // 定义int*类型指针pa存a的地址 char ch w; char *pc ch; // 定义char*类型指针pc存ch的地址 return 0; }2.3 解引用操作符 *通过地址访问变量拿到地址后用*操作符能通过地址找到变量类似按门牌号找宿舍这就是 “解引用”。代码示例#include stdio.h int main() { int a 10; int *pa a; // pa存a的地址 *pa 20; // 解引用通过pa的地址修改a的值 printf(a %d\n, a); // 输出a 20 return 0; }核心逻辑*pa等价于a通过指针修改*pa本质就是修改变量 a。2.4 指针变量的大小关键结论指针变量的大小只和系统位数有关和指向的类型无关32 位系统地址是 32 位4 字节所有指针变量都是 4 字节对应 VS2022 X64。64 位系统地址是 64 位8 字节所有指针变量都是 8 字节对应 VS2022 X86。代码验证#include stdio.h int main() { printf(char* 大小%zd\n, sizeof(char*)); printf(int* 大小%zd\n, sizeof(int*)); printf(double* 大小%zd\n, sizeof(double*)); return 0; }运行结果32 位环境4 4 464 位环境8 8 8三、指针类型的真正意义初学者易忽略既然指针变量大小和类型无关为什么还要分 int*、char*核心是两个关键作用3.1 决定解引用的 “操作权限”指针类型决定了解引用时能访问多少字节char*解引用访问 1 字节char 类型大小。int*解引用访问 4 字节int 类型大小。代码对比注意下面代码对应的注释是在它们上面在林锐前辈所著《高质量的 C/C 编程指南》中关于注释位置的规范表述为【规则 2-7-6】注释的位置应与被描述的代码相邻可以放在代码的上方或右方不可放在下方。详见《高质量 C/C 编程指南》注释规范 VS2022 模板// 代码1int* 解引用修改4字节 #include stdio.h int main() { // 定义4字节int型变量十六进制初始化 int n 0x11223344; // 指向int变量的指针 int* pi n; // 解引用修改整个4字节为0 *pi 0; // %#x强制输出0x前缀符合十六进制规范 printf(n %#x\n, n); // 稳定输出n 0x0 return 0; } // 代码2char* 解引用修改1字节 #include stdio.h int main() { // 4字节int型变量小端存储内存中字节顺序为 0x44 → 0x33 → 0x22 → 0x11低地址→高地址 int n 0x11223344; // 强制转换为char*仅指向首字节即0x44所在地址 char* pc (char*)n; // 仅修改首字节为0其余3字节保留 *pc 0; // 输出结果0x11223300 printf(n %#x\n, n); return 0; }你可能会发现代码 1 运行后输出的n 0没有显示0x前缀。这是因为 VS2022 的printf中%#x在值为 0 时的特殊表现 —— 当输出值是 0 时部分编译器包括 VS2022会省略0x前缀只显示0。解决方法让 0 也显示0x0把printf语句改成printf(n 0x%x\n, n); // 手动加0x前缀强制显示这样无论 n 是 0 还是其他值都会固定输出0x开头的十六进制格式比如 n0 时显示0x0n0x11223344 时显示0x11223344。3.2 决定指针 ± 整数的 “步长”指针 ± 整数时跳过的字节数 指针类型的大小char* 1跳过 1 字节char 大小。int* 1跳过 4 字节int 大小。代码验证#include stdio.h int main() { int n 10; char *pc (char*)n; int *pi n; printf(pc %p\n, pc); // 输出n的首地址如00AFF974 printf(pc1 %p\n, pc1); // 跳过1字节输出00AFF975 printf(pi %p\n, pi); // 输出00AFF974 printf(pi1 %p\n, pi1); // 跳过4字节输出00AFF978 return 0; }3.3 特殊类型void* 泛型指针void*是 “无类型指针”能接收任意类型的地址但有两个限制不能直接解引用。不能直接 ± 整数。用途常用于函数参数实现泛型编程比如接收 int、char、double 等任意类型地址。代码示例#include stdio.h int main() { int a 10; char ch w; void *pv1 a; // 合法void*接收int*地址 void *pv2 ch; // 合法void*接收char*地址 // *pv1 20; // 非法不能直接解引用 // pv1 1; // 非法不能直接±整数 return 0; }四、避坑指南const 修饰指针与野指针4.1 const 修饰指针控制修改权限const 放在*的左右意义完全不同记住口诀左定值右定针。指针类型含义能否修改指向的内容能否修改指针本身int *p普通指针能能const int *pint const *p指向 const 的指针左定值不能能int *const pconst 指针右定针能不能const int *const p指向 const 的 const 指针不能不能代码示例#include stdio.h int main() { int a 10, b 20; const int* p1 a; // *p1 30; // 错误不能修改指向的内容 p1 b; // 正确可以修改指针指向 printf(%d\n,*p1);//结果为20 int* const p2 a; *p2 30; // 正确可以修改指向的内容 // p2 b; // 错误不能修改指针指向 printf(%d\n, *p2);//结果为30 const int* const p3 a; // *p3 30; // 错误 // p3 b; // 错误 return 0; }4.2 野指针最危险的 “陷阱”野指针是指向未知地址的指针访问野指针会导致程序崩溃常见成因及规避方法4.2.1 野指针的 3 种成因指针未初始化局部指针变量默认是随机值。int *p; // 野指针p的值随机 *p 10; // 危险访问未知地址指针越界访问超出数组等合法空间范围。int arr[10] {0}; int *p arr[0]; for (int i 0; i 10; i) { *(p) i; // 当i10时p越界成为野指针 }指针指向的空间已释放返回局部变量的地址。int *test() { int n 10; return n; // n是局部变量函数结束后空间释放 } int main() { int *p test(); // p是野指针 *p 20; // 危险 return 0; }4.2.2 规避野指针的 4 个方法初始化指针不知道指向哪里时赋值为NULLC 语言定义的空指针值为 0。int *p NULL; // 合法空指针不指向任何有效地址避免指针越界访问范围不超过申请的内存空间。指针不用时置为NULL使用前检查有效性。int arr[10] {0}; int *p arr[0]; // 使用后置空 p NULL; // 使用前检查 if (p ! NULL) { *p 10; }不返回局部变量的地址。4.3 assert 断言调试时的“安全检查”从上面的“指针不用时置为NULL使用前检查有效性。”可以拓展出assertassert.h中的assert()宏能在运行时检查条件不符合则报错终止程序适合调试时使用。代码示例#include stdio.h #include assert.h void test(int *p) { assert(p ! NULL); // 断言p不是空指针 *p 20; } int main() { int a 10; int *p NULL; test(p); // 运行时断言失败报错并终止 return 0; }说明Release 版本中可通过定义#define NDEBUG禁用 assert不影响程序效率。详见Release 版本禁用 assertNDEBUG 的底层逻辑与效率优化五、实战场景指针与数组、函数传参指针的核心用途是简化数组操作和实现函数传址调用这是 C 语言的核心技巧。5.1 数组名的本质首元素地址数组名在绝大多数情况下等于首元素的地址只有两个例外sizeof(数组名)数组名表示整个数组计算数组总大小字节。数组名数组名表示整个数组取出整个数组的地址。代码验证#include stdio.h int main() { int arr[10] { 1,2,3,4,5,6,7,8,9,10 }; printf(arr[0] %p\n, arr[0]); // 首元素地址 printf(arr[0]1 %p\n, arr[0]1); // 首元素地址1 printf(arr %p\n, arr); // 等价于arr[0] printf(arr1 %p\n, arr1); // 等价于arr[0]1 printf(\n); printf(arr %p\n, arr); // 整个数组的地址值相同含义不同 printf(arr1 %p\n, arr1); // 整个数组的地址1与上面几句相比增加的不是四个字节而是40个字节 printf(\n); printf(sizeof(arr) %zd\n, sizeof(arr)); // 40字节10*4 return 0; }结果截图可以看到前两次的加一打印的结果都是只加了4个字节结合我们上面讲的指针 ± 整数时跳过的字节数 指针类型的大小可知数组名arr等价于arr[0]都是首元素地址指针类型都为int*而arr的类型则不同它是数组指针1后打印的结果大了40就是佐证5.2 用指针访问数组更灵活的方式因为arr arr[0]所以arr[i]等价于*(arr i)指针访问数组更灵活。代码示例#include stdio.h int main() { int arr[10] {1,2,3,4,5,6,7,8,9,10}; int *p arr; // 等价于int *p arr[0] int sz sizeof(arr)/sizeof(arr[0]); // 计算数组长度 // 用指针遍历数组 for (int i 0; i sz; i) { printf(%d , *(p i)); // 等价于p[i]、arr[i] } return 0; }5.3 一维数组传参的本质传递首元素地址数组传参时本质是传递首元素的地址因此函数形参可以写成数组形式或指针形式完全等价。注意函数内部不能用sizeof(arr)计算数组长度此时 arr 是指针计算的是指针大小。代码示例#include stdio.h // 形参写成数组形式 void print_arr1(int arr[], int sz) { for (int i 0; i sz; i) { printf(%d\n , arr[i]); } } // 形参写成指针形式等价 void print_arr2(int* arr, int sz) { for (int i 0; i sz; i) { printf(%d\n , *(arr i)); } } int main() { int arr[10] { 1,2,3,4,5,6,7,8,9,10 }; int sz sizeof(arr) / sizeof(arr[0]); print_arr1(arr, sz); // 传递首元素地址 print_arr2(arr, sz); return 0; }5.4 传址调用函数修改主调变量的值传值调用时函数形参是实参的副本修改形参不影响实参传址调用传递地址函数内部能直接修改主调变量。经典案例交换两个整数#include stdio.h // 传值调用失败修改的是副本 void Swap1(int x, int y) { int tmp x; x y; y tmp; } // 传址调用成功通过地址修改实参 void Swap2(int *px, int *py) { int tmp *px; *px *py; *py tmp; } int main() { int a 10, b 20; Swap1(a, b); printf(Swap1后a%d, b%d\n, a, b); // 输出10,20未交换 Swap2(a, b); printf(Swap2后a%d, b%d\n, a, b); // 输出20,10交换成功 return 0; }六、进阶内容二级指针与指针数组6.1 二级指针指向指针的指针指针变量也是变量有自己的地址二级指针就是用来存 “指针变量地址” 的变量。定义格式数据类型 ** 变量名代码示例#include stdio.h int main() { int a 10; int *pa a; // 一级指针存a的地址 int **ppa pa; // 二级指针存pa的地址 **ppa 20; // 等价于*pa 20最终修改a的值 printf(a %d\n, a); // 输出20 return 0; }核心逻辑*ppa访问 pa一级指针变量。**ppa访问 a最终变量。6.2 指针数组存放指针的数组指针数组是 “数组”每个元素都是指针地址格式数据类型 * 数组名[长度]。代码示例指针数组模拟二维数组#include stdio.h int main() { int arr1[] { 1,2,3,4,5 }; int arr2[] { 2,3,4,5,6 }; int arr3[] { 3,4,5,6,7 }; // 指针数组每个元素存一维数组的首地址 int* parr[3] { arr1, arr2, arr3 }; // 遍历模拟的二维数组 for (int i 0; i 3; i) { for (int j 0; j 5; j) { printf(%d , parr[i][j]); // 等价于*(parr[i] j) } printf(\n); } return 0; }运行结果1 2 3 4 5 2 3 4 5 6 3 4 5 6 7说明这种模拟不是真正的二维数组每行的数组在内存中不连续只是逻辑上的二维结构。七、总结本质关系地址 指针指针变量是存放地址的变量。核心操作取地址、*解引用通过地址访问变量。指针大小32 位系统 4 字节64 位系统 8 字节与类型无关。类型意义决定解引用的操作权限字节数和指针 ± 整数的步长。避坑要点初始化指针、避免越界、不用野指针、合理使用 const 和 assert。核心用途简化数组操作、实现传址调用修改主调变量。OK还是经典结尾嗯希望能够得到你的关注希望我的内容能够给你带来帮助希望有幸能够和你一起成长。写这篇博客的时候晚灯映着代码的微光指尖划过键盘的声响与夜色相融调试与发布的逻辑在屏上渐次明朗。东华逐梦码为径万里探真路自长。我走到阳台拍下了一张宿舍对面的照片作为本文的封面。
版权声明:本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!

西安专业做网站的公司传奇网站怎么制作教程

还在为Java应用与KingBaseES数据库的连接而烦恼吗?让我带你轻松掌握人大金仓JDBC驱动8.6.0版本的使用精髓,让数据通信变得简单而优雅。 【免费下载链接】人大金仓JDBC驱动包8.6.0版本 本仓库提供人大金仓 JDBC 驱动包的下载,版本为 8.6.0&…

张小明 2025/12/23 23:18:58 网站建设

网站建设的swot分析建设银行手机登陆网站

定制报告-个性化定制-按需专项研究报告-智信中科研究网市场专项研究报告智信中科研究网个性化定制报告全力解决您的各类需求,为了满足客户在不同发展阶段的不同需求,智信中科研究网可以依据客户的个性化需求,针对性帮助客户完成符合需求的市场…

张小明 2025/12/23 23:17:55 网站建设

seo网站设计网页单页设计西地那非片的副作用

终极指南:科大讯飞TTS引擎在Android上的完整应用方案 【免费下载链接】科大讯飞语音引擎TTS.apk下载 本仓库提供科大讯飞语音引擎TTS.apk的下载,支持32位和64位版本,适用于最新的Android系统。该语音引擎为Android平台提供中文发音的TTS&…

张小明 2025/12/23 23:15:50 网站建设

更换网站模板二类电商有哪些平台

终极指南:如何用Lago开源计费系统快速搭建企业级计费平台 【免费下载链接】lago Open Source Metering and Usage Based Billing 项目地址: https://gitcode.com/GitHub_Trending/la/lago Lago开源计费系统为企业提供了强大的使用计量和基于事件的计费解决方…

张小明 2025/12/23 23:14:47 网站建设

沧州做网站推广公司专门做图标的网站

课题介绍 本课题聚焦社区、企事业单位垃圾分类管理效率低、居民分类认知不足、分类数据统计分析难的痛点,设计实现基于 SpringBoot(Java)的环保垃圾分类管理系统。系统以 SpringBoot 为核心框架,整合 Spring MVC 完成请求处理与业…

张小明 2025/12/23 23:13:44 网站建设

seo网站排名优化公司哪家好wordpress 薄荷主题

终极方案:如何一劳永逸解决直播地址频繁失效问题 【免费下载链接】DouyinLiveRecorder 项目地址: https://gitcode.com/gh_mirrors/do/DouyinLiveRecorder 你是否曾因直播地址频繁失效而错过精彩内容?手动更新直播间链接不仅耗时费力&#xff0c…

张小明 2025/12/23 23:12:41 网站建设