C语言深入了解指针(2):const 修饰指针、野指针、assert 断言、传址调用
指针是 C 语言的灵魂也是很多初学者的拦路虎。上一篇我们认识了指针基础本篇继续深挖指针搞懂const修饰指针的两种写法、什么是野指针、如何规避野指针、assert断言工具以及最重要的传值调用与传址调用彻底理解为什么交换两个变量要传地址。一、const修饰指针1.1 const 修饰普通变量const的本意是限定变量不能直接被修改。constintn0;n20;// 编译报错不能直接修改n注意const修饰的本质还是变量不是常量。只是语法层面禁止直接赋值修改。还有一个小bug可以通过取地址用指针绕过语法限制去修改它的值。#includestdio.hintmain(){constintn0;printf(n %d\n,n);int*pn;*p20;// 绕过const限制修改nprintf(n %d\n,n);return0;}输出结果n 0n 20这就带来问题n被 const 保护但是指针拿到地址就可以篡改。所以我们需要用const来修饰指针限制指针的行为。1.2 const 修饰指针的两种核心写法const写在*左边和*右边含义完全不同在考题里面容易出现的知识题const int *p;const 在 * 左边保护指针指向的数据不能通过指针修改内容但是指针 p 本身可以改变指向别的变量。voidtest2(){intn10;intm20;constint*pn;*p20;// 报错不能修改指向的内容pm;// 指针p可以改指向}两边都加 constconst int * const p;既不能改指向内容也不能改变指针指向完全锁死。记忆口诀星号左边保护内容星号右边保护指针本身。二、野指针野指针指针指向的位置是随机、无效、未知的内存地址。野指针不是 NULL 指针NULL 是人为置 0 的有效标识野指针是乱码随机地址访问野指针会造成程序崩溃。2.1 野指针三大成因指针未初始化局部指针默认随机垃圾值intmain(){int*p;// 局部变量没有赋值存随机地址*p20;// 直接解引用野指针程序崩溃return0;}指针越界访问数组只有 10 个元素指针跑到数组内存外面。intmain(){intarr[10]{0};int*parr[0];inti0;for(i0;i11;i){*(p)i;// i超过9之后p越界变成野指针}return0;}返回局部变量的地址函数执行结束函数栈帧销毁局部变量内存被回收返回的地址变成无效地址。int*test(){intn100;returnn;// 返回局部变量地址高危}intmain(){int*ptest();printf(%d\n,*p);// p是野指针结果不可预测return0;}2.2 如何规避野指针指针一定要初始化不知道指向谁就赋值NULL知道指向谁就存合法变量地址。intnum10;int*p1num;int*p2NULL;// NULL代表不指向任何有效空间NULL本质#define NULL ((void*)0)地址 0操作系统保护禁止读写。杜绝指针越界严格控制访问范围指针不用的时候及时置 NULL使用前先判断是否为 NULLif(p!NULL){// 安全的解引用操作}严禁返回局部变量的地址通常口诀野指针 没人拴的野狗置 NULL 相当于把狗拴树上使用前判断 NULL 先看狗有没有拴不要乱碰。三、assert 断言调试工具头文件#include assert.hassert(表达式)运行时检测表达式如果表达式为假 (0)程序直接崩溃打印出错文件名 行号方便调试排错。//例子assert(p!NULL);如果p是 NULL程序直接终止提示哪一行出错assert 的开启与关闭如果发布正式版本不想保留断言带来的性能开销可以在包含头文件之前定义NDEBUG宏全部 assert 直接失效。#defineNDEBUG// 关闭所有assert#includeassert.h使用场景Debug 调试版本大量使用Release 发布版本禁用。注意assert 只做调试检查不能替代业务逻辑的if判断。示例模拟实现 strlen结合 constassert库函数原型size_t strlen ( const char * str );const char*保证函数内部不会修改传入字符串内容assert(str)保证传入指针不是 NULL#includestdio.h#includeassert.hintmy_strlen(constchar*str){assert(str);// 如果传NULL直接报错intcount0;while(*str)// *str不等于\0就循环{count;str;}returncount;}intmain(){intlenmy_strlen(abcdef);printf(%d\n,len);return0;}四、传值调用 vs 传址调用指针核心应用传值调用需求写函数交换两个 int 变量的值。//传值调用失败#includestdio.hvoidwap1(intx,inty){inttmpx;xy;ytmp;}intmain(){inta10;intb20;wap1(a,b);printf(a%d b%d,a,b);//输出 a10 b20交换失败return0;}失败的原因传值调用实参a、b把值拷贝一份给形参x、y。x、y 是函数内全新临时变量有自己独立内存。函数内部交换的只是副本和 main 里面 a、b 毫无关系。函数结束临时变量销毁main 的 a、b 纹丝不动。所有核心结论传值调用函数内部修改参数不影响外部实参。//传址调用成功//把变量的地址传给函数函数拿到地址间接操作 main 函数原始变量。#includestdio.hvoidwap2(int*px,int*py){inttmp0;tmp*px;*px*py;*pytmp;}intmain(){inta10;intb20;wap2(a,b);// 传入地址printf(a%d b%d,a,b);//输出 a20 b10交换成功return0;}传值调用和传址调用区别总结传值调用传递变量的值拷贝副本。函数只能读取数据不能修改外部实参。适合只拿数据做计算。传址调用传递变量地址。函数通过指针解引用可以修改主调函数里面原始变量什么时候用传址需要函数修改外面变量的值交换、输出多个结果传递大块数组避免整块拷贝提高效率五、总结const 修饰指针*左边保护指向内容*右边保护指针本身。野指针产生三原因未初始化、越界、返回局部变量地址4 种规避手段。assert调试断言Debug 开启Release 用NDEBUG关闭。传值调用拷贝副本改不了外部变量传址调用传地址可以修改外部变量。

相关新闻

CPG控制网络入门:从振荡器到四足机器人实时步态生成

CPG控制网络入门:从振荡器到四足机器人实时步态生成

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/4 4:48:30 阅读更多 →
YOLOv5车牌检测与OCR识别两段式架构实战指南

YOLOv5车牌检测与OCR识别两段式架构实战指南

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/4 4:48:30 阅读更多 →
C/C++ 内存管理详解:从内存分布到 new/delete 底层原理

C/C++ 内存管理详解:从内存分布到 new/delete 底层原理

C/C 内存管理详解:从内存分布到 new/delete 底层原理 文章目录C/C 内存管理详解:从内存分布到 new/delete 底层原理一、C/C 程序的内存分布1 栈区2 堆区3 数据段4 代码段二、通过代码判断变量到底在哪里1 globalVar2 staticGlobalVar3 staticVar4 localV…

2026/10/4 4:48:30 阅读更多 →

最新新闻

STM32F103C8T6+CubeMX+FreeMODBUS工业级Modbus从机实战

STM32F103C8T6+CubeMX+FreeMODBUS工业级Modbus从机实战

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/4 5:31:53 阅读更多 →
STM32F103RC裸机入门:从PC7点亮LED到寄存器级开发

STM32F103RC裸机入门:从PC7点亮LED到寄存器级开发

1. 为什么选STM32F103RC作为入门第一块“真”MCU刚接触嵌入式开发的朋友,大概率是从51单片机或Arduino起步的。但真正想把底层逻辑吃透、能独立调试外设、看懂寄存器手册、写出不依赖库函数的裸机代码,STM32F103RC就是绕不开的第一道硬门槛。它不是最便宜…

2026/10/4 5:31:53 阅读更多 →
JavaEE宠物领养网站毕设实战:JSP+Servlet+MySQL从设计到实现

JavaEE宠物领养网站毕设实战:JSP+Servlet+MySQL从设计到实现

简介:宠物领养网站是JavaEE方向经典的毕业设计选题,这份论文文档围绕“基于JavaEE下宠物领养网站的设计与实现”展开,定位为计算机专业学生完成毕设的参考范例。文档从课题背景与国内外现状切入,依次介绍需求分析、系统设计、数据…

2026/10/4 5:31:53 阅读更多 →
Java+Swing+MySQL教材管理系统课设源码解析与避坑指南

Java+Swing+MySQL教材管理系统课设源码解析与避坑指南

简介:这份资源是面向高校学生与Java初学者的一套教材管理系统源代码,适合作为课程设计、毕业设计或Swing桌面开发练手项目。系统围绕管理员对教材的日常管理展开,涵盖教材信息录入、按教材号查询、入库与出库、库存查询以及统计打印等核心业务…

2026/10/4 5:31:53 阅读更多 →
智慧医院门诊管理系统Java课设项目:从源码拆解到部署避坑实战

智慧医院门诊管理系统Java课设项目:从源码拆解到部署避坑实战

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/4 5:31:53 阅读更多 →
使用 Symfony Notifier 集成 Sinch SMS:DSN 配置与发送原理全解析

使用 Symfony Notifier 集成 Sinch SMS:DSN 配置与发送原理全解析

后端Web框架 【免费下载链接】symfony The Symfony PHP framework 项目地址: https://gitcode.com/GitHub_Trending/sy/symfony 点击查看 免费下载 Sinch 是全球知名的云通信服务商,提供短信、语音与验证码等能力。Symfony 的 Notifier 组件通过 symfon…

2026/10/4 5:30:52 阅读更多 →

日新闻

KT148A语音芯片外挂8002D功放的工程实践指南

KT148A语音芯片外挂8002D功放的工程实践指南

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/4 1:00:58 阅读更多 →
LLC谐振变换器增益公式推导:从FHA等效到完整归一化表达式

LLC谐振变换器增益公式推导:从FHA等效到完整归一化表达式

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/4 1:00:58 阅读更多 →
ARM架构深度解析:从RISC设计理念到交叉编译实战

ARM架构深度解析:从RISC设计理念到交叉编译实战

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/4 1:00:58 阅读更多 →

周新闻

KT148A语音芯片外挂8002D功放的工程实践指南

KT148A语音芯片外挂8002D功放的工程实践指南

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/4 1:00:58 阅读更多 →
LLC谐振变换器增益公式推导:从FHA等效到完整归一化表达式

LLC谐振变换器增益公式推导:从FHA等效到完整归一化表达式

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/4 1:00:58 阅读更多 →
ARM架构深度解析:从RISC设计理念到交叉编译实战

ARM架构深度解析:从RISC设计理念到交叉编译实战

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/4 1:00:58 阅读更多 →

月新闻

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/2 10:36:31 阅读更多 →
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/3 9:42:35 阅读更多 →
黑夜航拍船只数据集训练YOLOV5模型全流程解析

黑夜航拍船只数据集训练YOLOV5模型全流程解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/3 9:42:36 阅读更多 →