【C语言】指针(1)——指针简单介绍及指针相关运算
目录1.内存和地址2.指针变量和地址2.1取地址操作符2.2指针变量和解引用操作符2.2.1指针变量2.2.2如何理解 int * p 如何拆解指针类型2.2.3解引用操作符*2.2.4指针变量的大小3.指针变量类型的意义3.1指针-整数3.2void*4.const修饰指针4.1 const修饰变量4.2 const修饰指针变量5.指针运算5.1指针-指针5.2指针-指针5.3指针的关系运算6.野指针6.1野指针成因1.指针未初始化2.指针越界访问3.指针指向的空间释放6.2如何规避野指针6.2.1指针初始化6.2.2小心指针越界6.2.4避免返回局部变量的地址7.assert断言8.传值调用和传址调用1.内存和地址计算机中最小的单位是比特位bit可以用来存储1个二进制位1byte 8bit 1KB 1024byte 1MB 1024KB 1GB 1024MB 1TB 1024GB 1PB 1024TB内存单元编号 地址 指针计算机中的编址不是把每个字节的地址记录下来而是通过硬件设计完成的。地址总线32位机器有32根地址总线可以表示2^32种含义每种含义表示一个地址。2.指针变量和地址2.1取地址操作符在C语言中创建变量的本质就是向内存申请空间。%p可以用来打印地址使用取出地址单目操作符a取出的是a所占四个字节中较小的字节的地址#includestdio.h int main() { int a 0; // 为a申请4个字节的空间 int *p a; return 0; }2.2指针变量和解引用操作符2.2.1指针变量使用取地址操作符取出的地址是一个数值需要存储在指针变量中。上述代码中p是一个指针变量。指针变量也是变量是用来存放地址的存放在指针变量中的值会被理解为地址。指针地址指针变量存放地址的变量口语中的指针一般指指针变量2.2.2如何理解 int * p 如何拆解指针类型*说明p是一个指针变量int说明p指向的对象是int类型同样的若p指向的类型是char类型定义时要使用char*2.2.3解引用操作符*解作符*又叫间接访问操作符*p表示通过p存放的地址找到p指向的对象可以通过*p间接访问p指向的对象例如可以通过*p0将p指向的对象的值变为0*和是可以相抵消的*a a2.2.4指针变量的大小32位机器假设有32根地址总线每根地址总线的电信号转换成数字信号后都表示0或1如果将32根地址总线产生的二进制序列当做一个地址那么该地址就需要32个bit位进行存储即32位机器的地址变量的大大小为4个字节。同理64位机器中的地址变量的大小为8个字节指针变量的大小与其所指向的对象类型无关只要是指针变量在相同平台上的大小都是相同的。如图在x86即32位环境下各种类型的指针变量大小均为4字节在x64即64位环境下均为8字节。3.指针变量类型的意义既然在同一个平台下各种类型的指针变量的大小是相同的为什么还要有各种各样的指针类型呢因为指针类型决定了对指针进行解引用操作时有多大的权限。比如char*指针在解引用时只能访问一个字节int*指针解引用时可以访问4个字节。3.1指针-整数#includestdio.h int main() { int a 10; int* pa a; char* pc (char*) a; printf(pa %p\n, pa); printf(pa1 %p\n, pa1); printf(pc %p\n, pc); printf(pc1 %p\n, pc1); return 0; }运行结果可以看出当int*类型的pa进行1操作时地址由006FFC08变为006FFC0C向后移动了4个字节sizeof(int)而char*类型的pc1时由006FFC08变为006FFC09向后移动了1个字节sizeof(char)。这就是不同指针变量类型的差别。结论指针类型决定了指针向前或向后一步有多大字节。3.2void*在指针类型中有一种特殊类型是void*类型的可以理解为无具体类型的指针或泛型指针。这种指针可以用来接受各种类型的地址但是也有局限性void*类型的指针不能直接进行指针-整数和解引用的运算。一般情况下void*类型的指针使用在函数参数的部分用来接收不同数据类型的地址可以实现泛型编程的效果使一个函数可以处理多种类型的数据。4.const修饰指针4.1 const修饰变量const int a 10; // a具有了常属性不能被修改在c语言中虽然a不能被修改了但本质上还是变量常变量在c中const修饰的变量就是常量被const修饰的变量可以通过指针修改破坏规则4.2 const修饰指针变量//代码1 void test1() { int n 10; int m 20; int* p n; *p 20;//ok? p m; //ok? } void test2() { //代码2 int n 10; int m 20; const int* p n; *p 20;//报错 p m; //ok? } void test3() { int n 10; int m 20; int* const p n; *p 20; //ok? p m; //报错 } void test4() { int n 10; int m 20; int const* const p n; *p 20; //报错 p m; //报错 } int main() { //测试⽆const修饰的情况 test1(); //测试const放在*的左边情况 test2(); //测试const放在*的右边情况 test3(); //测试*的左右两边都有const test4(); return 0; }一般来说const可以放在*的左边也可以放在*的右边当const放在*左边修饰的是指针指向的内容确保指针指向的内容不能通过指针改变但指针变量内容本身可以改变。当const放在*右边修饰的是指针变量本身保证了指针变量本身的内容不能修改但是指针指向的内容可以通过指针改变。也可以同时放在*左边和右边表示指针指向的内容和指针变量本身均不能修改。5.指针运算指针运算有三种分别是1指针-指针2指针-指针3指针的关系运算5.1指针-指针因为数组在内存中是连续存放的所以只要知道第一个元素的地址就可以找到后面所有元素。Type * p;p1 -- 跳过 1*sizeof(type)pn -- 跳过 n*sizeof(type)#includestdio.h int main() { int arr[10] { 0,1,2,3,4,5,6,7,8,9 }; int* p arr[0]; int sz sizeof(arr) / sizeof(arr[0]); for (int i 0; i sz; i) { printf(%d\n, *(p i)); } return 0; }以上代码可用于输出数组元素5.2指针-指针|指针-指针| 两指针间的元素个数前提两指针指向同一块空间如指向同一个数组不存在指针指针无意义5.3指针的关系运算指针的关系运算实际上就是指针和指针比较大小可以用来判断指针是否指向数组内、6.野指针概念野指针就是指针指向的位置是不可知的随机的不正确的没有明确限制的6.1野指针成因1.指针未初始化指针变量未初始化默认为随机值2.指针越界访问eg.当指针指向的范围超出数组范围时就成为野指针3.指针指向的空间释放eg.函数结束后指针指向的变量被释放p成为野指针6.2如何规避野指针6.2.1指针初始化指针初始化有两种情况1.明确知道指针应该指向哪里初始化一个明确的地址2.暂时不知道指针应该指向哪里初始化为NULLNULL是C语言中定义的标识符常量值为0,0也是地址这个地址是无法使用的读写该地址会报错6.2.2小心指针越界一个程序向内存申请了多少空间通过指针也就只能访问那些空间不能超出访问范围超出了就是越界访问。6.2.3指针变量不再使用时及时置为NULL指针使用前检查有效性。不再使用某个指针时要将指针置为NULL使用指针前先判断指针是否为NULL6.2.4避免返回局部变量的地址7.assert断言assert.h头文件定义了宏assert()用于在运行时确保特定程序符合指定条件如果不符合就报错终止运行这个宏常被称为“断言”。assert(p) //判断p是否为空指针等价于assert(p!NULL)assert()宏接受一个表达式作为参数任意表达式。如果该表达式为真返回值非零assert()不会有任何反应程序继续运行如果该表达式为假返回值为零assert()就会报错在标准错误流stderr中写入一条错误信息显示错误的表达式及其所在的文件名及行号。使用assert()的好处1.可以自动标识文件和出问题的行号2.如果已经确保程序没有问题不再需要assert()断言就在#includeassert.h前定义一个宏NDEBUG。然后重新编译编译器就会自动禁用文件中的所有assert()语句。#define NDEBUG #includeassert.hassert()的缺点因为引入了外部的检查增加了程序的运行时间。在vs中Release版本直接将assert()优化掉了在linux版本中Release版本仍会起作用。8.传值调用和传址调用传值调用把变量本身传递给函数。实参传递给形参时形参会单独创建一份临时空间来接收实参对形参的修改不会影响实参。传址调用把变量的地址传递给函数。可以让函数和主调函数之间建立真正的联系在函数内部可以修改主调函数中的变量。如果函数中只是需要主调函数中的变量值进行运算可以采用传值调用如果函数内部要修改主调函数变量的值就要采用传址调用。完

相关新闻

Spring Cloud Contract消息契约测试:AMQP、Kafka与JMS集成实战指南

Spring Cloud Contract消息契约测试:AMQP、Kafka与JMS集成实战指南

Spring Cloud Contract消息契约测试:AMQP、Kafka与JMS集成实战指南 【免费下载链接】spring-cloud-contract Support for Consumer Driven Contracts in Spring 项目地址: https://gitcode.com/gh_mirrors/sp/spring-cloud-contract 在分布式微服务架构中&am…

2026/10/16 4:50:23 阅读更多 →
题解:洛谷 B3927 [GESP202312 四级] 小杨的字典

题解:洛谷 B3927 [GESP202312 四级] 小杨的字典

本文分享的必刷题目是从蓝桥云课、洛谷、AcWing等知名刷题平台精心挑选而来,并结合各平台提供的算法标签和难度等级进行了系统分类。题目涵盖了从基础到进阶的多种算法和数据结构,旨在为不同阶段的编程学习者提供一条清晰、平稳的学习提升路径。 欢迎大家订阅我的专栏:算法…

2026/10/17 5:49:03 阅读更多 →
BabelDOC:终极智能PDF文档翻译工具,3步实现专业级双语对照

BabelDOC:终极智能PDF文档翻译工具,3步实现专业级双语对照

BabelDOC:终极智能PDF文档翻译工具,3步实现专业级双语对照 【免费下载链接】BabelDOC Yet Another Document Translator 项目地址: https://gitcode.com/GitHub_Trending/ba/BabelDOC 还在为技术文档翻译后的格式错乱而烦恼吗?BabelDO…

2026/10/17 6:36:25 阅读更多 →

最新新闻

OSPF多区域实战:LSA类型、ABR机制与特殊区域配置

OSPF多区域实战:LSA类型、ABR机制与特殊区域配置

很多人学OSPF时,单区域配置玩得很溜,一到多区就懵了:明明就是两条network命令的事,为什么还要分骨干区、特殊区,甚至搞出一堆LSA类型?更麻烦的是,多区之后再看路由表,你会发现区域间…

2026/10/18 20:43:12 阅读更多 →
Ruby on Rails 机票电商项目实战:搜索、下单、支付回调全链路拆解

Ruby on Rails 机票电商项目实战:搜索、下单、支付回调全链路拆解

简介:eyoo:旅游机票电商平台(重构版)是一份基于Ruby技术栈的在线机票销售系统源码,面向具备一定Web开发基础、希望深入理解电商平台架构的开发者与学习者。项目围绕Ruby语言与Rails框架展开,涵盖MVC分层、ActiveRecord…

2026/10/18 20:43:12 阅读更多 →
Cursor与Claude Code Skills实战:8类技能提升AI编程效率

Cursor与Claude Code Skills实战:8类技能提升AI编程效率

过去半年,我把 Cursor 和 Claude Code 当成了日常开发的主力编辑器,基本告别了“自己写一遍再让 AI 重写一遍”的低效循环。真正让这两个工具从“聊天机器人”变成“团队协作者”的,不是模型版本升级,而是 Skills。这个词最近火得…

2026/10/18 20:43:12 阅读更多 →
JSP+SSM医院住院系统:真实临床业务闭环实现

JSP+SSM医院住院系统:真实临床业务闭环实现

简介:这是一套面向计算机专业本科生的Java Web毕业设计实战项目,聚焦医院住院管理业务场景,适用于课程设计、毕设选题与SSM框架入门实践。资源完整包含可运行源码、功能演示视频及详细说明文档,帮助学习者掌握B/S架构下医疗信息系…

2026/10/18 20:43:12 阅读更多 →
Android Compose AI组件库:从流式文本到图像生成的架构实践

Android Compose AI组件库:从流式文本到图像生成的架构实践

最近在忙一个跨平台的智能应用项目,AI能力要在Android端做完整的对话、图片生成、语义搜索体验。搭到第三块页面的时候我就开始烦了:每次都是把网络流、状态管理、UI拼装从头粘一遍,代码长得几乎一样,效果却总有细微出入。后来看到…

2026/10/18 20:43:12 阅读更多 →
MCP Client 与 LLM 协作实战:工具调用与上下文管理全解析

MCP Client 与 LLM 协作实战:工具调用与上下文管理全解析

1. 从项目背景说起:MCP 到底解决了什么问题说到 MCP(Model Context Protocol,模型上下文协议),我先讲一个痛点场景。假设你手里有 5 个 AI 应用,想给每个应用接上 3 类外部能力:数据库查询、文件…

2026/10/18 20:42:12 阅读更多 →

日新闻

基于GMM的语音识别系统原理与MATLAB实现详解

基于GMM的语音识别系统原理与MATLAB实现详解

说到基于高斯混合模型(GMM)的语音识别系统,很多人第一反应就是一堆数学公式,觉得门槛很高。但如果你真的在MATLAB里把它落地跑通,会发现核心其实就是三件事:把声音变成特征向量,用GMM给每个类别…

2026/10/18 0:00:55 阅读更多 →
数字图像处理入门:反白、灰度化、调色板修改与导出txt实践

数字图像处理入门:反白、灰度化、调色板修改与导出txt实践

数字图像处理这四个字听起来挺唬人,但落到具体操作上,无非就是让计算机按你的想法“摆弄”像素。我在一个模拟项目X里用了一套特别经典的基础处理流程:对图像做反白、改调色板、彩色转灰度,最后把像素数据导出成txt文件。单看每一…

2026/10/18 0:00:55 阅读更多 →
机器人大脑技术盘点:具身智能的感知、决策与数据闭环

机器人大脑技术盘点:具身智能的感知、决策与数据闭环

如果你的信息流最近也天天刷到“机器人大脑”这个词,你会发现一个很有意思的现象:每个人说的“大脑”根本不是同一个东西。有人指的是大语言模型,有人指的是运动控制系统,还有人指的是能理解物理世界的端到端模型。在2026年这个时…

2026/10/18 0:00:55 阅读更多 →

周新闻

基于GMM的语音识别系统原理与MATLAB实现详解

基于GMM的语音识别系统原理与MATLAB实现详解

说到基于高斯混合模型(GMM)的语音识别系统,很多人第一反应就是一堆数学公式,觉得门槛很高。但如果你真的在MATLAB里把它落地跑通,会发现核心其实就是三件事:把声音变成特征向量,用GMM给每个类别…

2026/10/18 0:00:55 阅读更多 →
数字图像处理入门:反白、灰度化、调色板修改与导出txt实践

数字图像处理入门:反白、灰度化、调色板修改与导出txt实践

数字图像处理这四个字听起来挺唬人,但落到具体操作上,无非就是让计算机按你的想法“摆弄”像素。我在一个模拟项目X里用了一套特别经典的基础处理流程:对图像做反白、改调色板、彩色转灰度,最后把像素数据导出成txt文件。单看每一…

2026/10/18 0:00:55 阅读更多 →
机器人大脑技术盘点:具身智能的感知、决策与数据闭环

机器人大脑技术盘点:具身智能的感知、决策与数据闭环

如果你的信息流最近也天天刷到“机器人大脑”这个词,你会发现一个很有意思的现象:每个人说的“大脑”根本不是同一个东西。有人指的是大语言模型,有人指的是运动控制系统,还有人指的是能理解物理世界的端到端模型。在2026年这个时…

2026/10/18 0:00:55 阅读更多 →

月新闻

我发现了一个新思路:用 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/18 0:55:02 阅读更多 →
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/17 17:22:31 阅读更多 →
黑夜航拍船只数据集训练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/18 12:16:16 阅读更多 →