0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

C进阶技巧:二级指针问题

Q4MP_gh_c472c21 来源:最后一个bug 作者:bug菌 2020-09-08 15:00 次阅读
加入交流群
微信小助手二维码

扫码添加小助手

加入工程师交流群

1、先把问题摆出来

参考Demo:

1#include 2#include 3 4/************************************ 5*Fuction:测试demo 6*Author:(公众号:最后一个bug) 7***********************************/ 8intmain(intargc,char*argv[]){ 9inta=10; 10int*ptr=&a; 11int**ptrptr=&ptr; 12 13printf("*ptr=%d ",*ptr); 14printf("**ptrptr=%d ",**ptrptr); 15printf("**((int**)ptr)=%d ",**((int**)ptr)); 16printf("欢迎关注公众号:最后一个bug "); 17return0; 18}

运行结果:

现象描述:

大家可以看到当试图输出**((int **)ptr)的时候程序奔溃了,其实在bug菌刚开始学习C的时候也是遇到了这个问题,最终理解清楚了就自然明白了。粗暴点就把((int **)ptr);*((int **)ptr);**((int **)ptr)都尝试着打印出来分析分析。

所以bug菌在下面把指针的一些知识点都跟大家讲解一下,形成系统的知识,避免一些小伙伴仅学习了一些碎片而一知半解。

2、二级指针的使用

1

多级指针 其实多级指针在嵌入式程序中的应用还是相对比较少的,超过3级的bug菌仅仅只在一个特殊的索引功能里面使用过。 这里重点看看一、二级,毕竟二级指针与我们的二维数据结合使用,二维素组在图形、矩阵、算法等等方面还是使用非常广泛的。

2

一级指针 指针其实广义的讲它也是一种数据类型,所以所谓的int* ptr;其中int* 就是变量ptr的类型,那么ptr就是我们常说的指针变量。

Demo:

1#include 2#include 3/************************************ 4*Fuction:测试demo 5*Author:(公众号:最后一个bug) 6***********************************/ 7intmain(intargc,char*argv[]){ 8inta=10; 9int*ptr=&a; 10 11printf("a=%d ",a); 12printf("&ptr=0x%X ",&ptr); 13printf("&a=0x%X ",&a); 14printf("ptr=0x%X ",ptr); 15printf("*ptr=%d ",*ptr); 16 17printf("欢迎关注公众号:最后一个bug "); 18return0; 19}

运行结果:

图解:

分析一下:

ptr既然是变量,变量存于内存中,那么就一定有其地址,如上图所示ptr位于0x28FEE8地址处,其中其ptr里面保存的就是蓝色区域中的地址,也就是a变量所在的地址,所以&a与ptr是相等的。

*ptr就很好理解了,你可以把*ptr看成一个变量,其类型为int,其变量位于ptr值所在的内存地址处,即0x28FEEC处的int变量与定义的int a刚好一致。

3

二级指针 如果大家已经理解了一级指针,二级指针也就顺理成章了,来看看下面的小程序:

Demo:

1#include 2#include 3/************************************ 4*Fuction:测试demo 5*Author:(公众号:最后一个bug) 6***********************************/ 7intmain(intargc,char*argv[]){ 8inta=10; 9int*ptr=&a; 10int**ptrptr=&ptr; 11 12printf("a=%d ",a); 13 14printf("&ptrptr=0x%X ",&ptrptr); 15 16printf("ptrptr=0x%X ",ptrptr); 17printf("&*ptrptr=0x%X ",&*ptrptr); 18printf("&ptr=0x%X ",&ptr); 19 20printf("*ptrptr=0x%X ",*ptrptr); 21printf("ptr=0x%X ",ptr); 22 23printf("*ptr=%d ",*ptr); 24printf("**ptrptr=%d ",**ptrptr); 25 26printf("欢迎关注公众号:最后一个bug "); 27return0; 28}

运行结果:

图解:

分析一下:

通过上图来看ptrptr也是一个变量,其类型为int**,变量肯定有内存,其地址就是0x28FEE4,其变量保存的值是0x28FEE8(即ptr的地址)。

那么*ptrptr,同样跟一级指针一致,把*ptrptr看成一个变量,也就是在ptrptr的值0x28FEEC8地址处的一个int*类型的变量,且该变量的值是0x28FEEC,其自身的地址为0x28FEE8。

同样对于**ptrptr也看成变量,也就是*ptrptr的值0x28FEEC地址处的一个int类型的变量,那么此时该变量与a是相等的。

最后在解释一下&*ptrptr,由于*ptrptr一个变量,&*ptrptr表示该变量的地址即0x28FEE8,然而该值刚好也是ptrptr变量的值,所以&*ptrptr =ptrptr。

3、是时候解答前面的问题了

参考Demo:

1#include 2#include 3 4/************************************ 5*Fuction:测试demo 6*Author:(公众号:最后一个bug) 7***********************************/ 8intmain(intargc,char*argv[]){ 9inta=10; 10int*ptr=&a; 11int**ptrptr=&ptr; 12 13printf("*ptr=%d ",*ptr); 14printf("**ptrptr=%d ",**ptrptr); 15printf("**((int**)ptr)=%d ",**((int**)ptr)); 16printf("欢迎关注公众号:最后一个bug "); 17return0; 18}

分析一下:

我们知道问题出在**(int**)ptr,不太理解的小伙伴总是觉得,我已经强制类型转化为二级指针了,前面只需要用**获得最后的值即可,怎么就不行呢? 我知道这里有问题我就是不理解为什么?

那我们一起通过前面的知识来分析分析。同样把ptr看成是变量,变量的值并不会跟随强制类型而发生改变。强制类型仅仅只是改变了获取内存中数据的方式,并没有改变内存中的数据。下面图解一下:

所以本例子中对于强制类型转化中的**(int*****)ptr,无论强制类型转化为几级指针都没有丝毫意义,因为变量本身的值没有发生变化!所以强制类型转化以后第二个*便会指向出问题,从而导致访问了不正确的内存空间而程序奔溃。

多级指针强制类型转化的目的大部分都是为了满足编译器检查指针层级操作逻辑是否有误。

以后大家对于多级指针的分析不太熟练的话可以跟bug菌一样画画图分析分析,基本上一些理解上的问题就迎刃而解了。

4、最后小结

指针的理解就为大家讲解到这里了,如果你对指针还有畏惧感,那就只有一个可能,使用得太少了,多加练习自然生巧!

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • 算法
    +关注

    关注

    23

    文章

    4800

    浏览量

    98512
  • 矩阵
    +关注

    关注

    1

    文章

    450

    浏览量

    36239
  • 嵌入式程序
    +关注

    关注

    0

    文章

    6

    浏览量

    6718

原文标题:C进阶技巧:二级指针这个问题被问好几遍!该终结了!

文章出处:【微信号:gh_c472c2199c88,微信公众号:嵌入式微处理器】欢迎添加关注!文章转载请注明出处。

收藏 人收藏
加入交流群
微信小助手二维码

扫码添加小助手

加入工程师交流群

    评论

    相关推荐
    热点推荐

    C++ 11 14 17 20内存管理-指针、智能指针和内存池基础与提升

    pan.baidu.com/s/1g64x9D_jp9ufk4uBpQBmvA?pwd=497f  未来 C++ 底层核心:内存管理实战,从指针到内存池全链路进阶 站在2026年的技术潮头,当AI
    的头像 发表于 04-20 15:51 492次阅读

    芯盛智能XT6160企业SSD主控芯片通过国家商用密码产品二级认证

    近日,芯盛智能XT6160企业SSD主控芯片正式通过国家密码管理局商用密码检测认证,达到GM/T 0008《安全芯片密码检测准则》第二级要求,获颁商用密码产品认证证书。这是芯盛智能继XT8210
    的头像 发表于 03-17 10:21 532次阅读
    芯盛智能XT6160企业<b class='flag-5'>级</b>SSD主控芯片通过国家商用密码产品<b class='flag-5'>二级</b>认证

    什么是B+C电源防雷器?

    防雷器应运而生。这种复合型防雷器又被称为一、二级复合型电涌保护器,它巧妙地结合了B类(Ⅰ)防雷器的大通流能力和C类(Ⅱ)防雷器的低残压特性,是现代建筑物电源进线保
    的头像 发表于 03-10 17:36 1104次阅读
    什么是B+<b class='flag-5'>C</b><b class='flag-5'>级</b>电源防雷器?

    C语言重点—指针

    C语言是比较偏底层的语言,为什么他比较偏底层,就是因为他的很多操作都是直接针对内存操作的。 这篇我们就来讲解C语言的一大特点,也是难点,指针指针操作。 这篇文章我会先从基本类型的存储
    发表于 01-22 08:23

    指针的基础

    二级指针,用于存放一个内存的地址,该地址对应的内存中存放了另一个整型变量的地址 比如: int va=0x12345678; int *pva =va; int **ppva =pva;
    发表于 12-15 06:06

    二级差分电路的电阻怎么配置?

    想问下,二级差分电路的电阻该怎么配置呢?
    发表于 10-16 15:05

    配电柜二级浪涌保护器的安装选型与行业应用方案

    IEC 61643-11及我国GB/T 18802.1-2011标准,SPD分为: Ⅰ(B):用于建筑物总配电柜,防直击雷及大能量冲击; ⅡC
    的头像 发表于 09-28 14:40 1327次阅读
    配电柜<b class='flag-5'>二级</b>浪涌保护器的安装选型与行业应用方案

    德州仪器模拟设计|使用第二级滤波器来减少电压纹波

    在上期中,我们探讨了高速 ADC 模拟输入前端的各种无源匹配技巧。   本期,为大家带来的是《使用第二级滤波器来减少电压纹波》,将对比三种控制架构在相同输出电压纹波下的表现,并提供了使用相同电气规格
    的头像 发表于 09-08 09:23 1662次阅读
    德州仪器模拟设计|使用第<b class='flag-5'>二级</b>滤波器来减少电压纹波

    嵌入式从入门到进阶,怎么学?

    嵌入式从入门到进阶,怎么学? 嵌入式学习的核心是 “软硬结合的技术壁垒”,科学分层才能高效突破。以下是从入门到高阶的精简路线,帮你避开弯路: 1、基础奠基层:构建技术底座 C 语言聚焦 指针、结构体
    发表于 09-02 09:44

    HarmonyOS NEXT应用元服务常见列表操作二级联动

    二级联动场景 场景描述 通过左边一列表的选择,联动更新右边二级列表的数据,常用于商品分类选择、编辑风格等二级类别选择页面。 本场景以商品分类列表页面为例,分别通过List组件,对左侧
    发表于 07-02 10:29

    二级浪涌电路之保险丝选型

    点在哪里呢? 本文通过DC110V接口保护电路的设计,讲解二级防雷电路中退耦电感的选型。 、设计方案 防护器件的选择相对来讲比较直观,器件厂家会提供器件的额定工作电压、击穿电压、嵌位电压等参数,甚至
    发表于 06-28 22:00

    由 Mybatis 源码畅谈软件设计(八):从根上理解 Mybatis 二级缓存

    1. 验证二级缓存 在上一篇帖子中的 User 和 Department 实体类依然要用,这里就不再赘述了,要启用二级缓存,需要在 Mapper.xml 文件中指定 cache 标签,如下
    的头像 发表于 06-23 11:35 567次阅读
    由 Mybatis 源码畅谈软件设计(八):从根上理解 Mybatis <b class='flag-5'>二级</b>缓存

    澜起科技M88STAR5芯片喜获国密二级安全认证

    近日,澜起科技自主研发的数据保护与可信计算加速芯片M88STAR5成功通过GM/T 0008《安全芯片密码检测准则》第二级要求 ,荣获商用密码检测认证中心颁发的 《商用密码产品认证证书》 。这一
    的头像 发表于 06-23 09:31 7344次阅读

    蔡司培训|提升技能必看——AUKOM 一/二级课程培训

    AUKOM 一课程通过系统的分析测量误差,即工件、环境、测量机、操作人员、测量策略,五个方面分析误差因子,保证策量结果的准确性。 AUKOM 二级课程是在AUKOM 一的基础上,更深入的展开
    发表于 06-03 14:26 2351次阅读
    蔡司培训|提升技能必看——AUKOM 一<b class='flag-5'>级</b>/<b class='flag-5'>二级</b>课程培训

    二级浪涌电路之退耦电感选型

    二级浪涌防雷电路设计
    的头像 发表于 05-12 15:31 2615次阅读
    <b class='flag-5'>二级</b>浪涌电路之退耦电感选型