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

    文章

    4599

    浏览量

    92642
  • 矩阵
    +关注

    关注

    0

    文章

    422

    浏览量

    34500
  • 嵌入式程序
    +关注

    关注

    0

    文章

    6

    浏览量

    6526

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

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

收藏 人收藏

    评论

    相关推荐

    CDCE62005第二级PLL无法锁住的原因?如何解决?

    我们遇到两片CDCE62005联后,部分板卡第二级芯片Lock信号失锁问题。 我们的芯片电路是完全参考TI官方6678开发板的,配置的SPI接口由FPGA控制,配置文件由官方软件生成; 已经生产
    发表于 11-11 07:06

    二级浪涌保护器的区别与选型指南

    尤为重要。地凯科技将深入分析一二级浪涌保护器的主要区别、识别方法、选择依据及不同行业中的细分应用。 一浪涌保护器与二级浪涌保护器的定义与工作原理 一
    的头像 发表于 11-08 11:04 145次阅读
    一<b class='flag-5'>级</b>和<b class='flag-5'>二级</b>浪涌保护器的区别与选型指南

    二级配电箱的作用介绍

    配电箱作为电能分配和管理的关键设备,发挥着至关重要的作用。二级配电箱位于一配电箱和三配电箱之间,起到中间分配电力的作用。本文将深入探讨二级配电箱的主要特点和功能,为电力系统的优化提
    的头像 发表于 10-04 11:46 296次阅读

    INA128两放大,第二级放大测不出来的原因?如何解决?

    放大 第一放大6倍第二级放大16倍 信号源输入2v电压示波器显示第一放大只有5.2倍第二级放大测不出来当两
    发表于 09-12 06:51

    THS3001联组成放大电路,实际接通后第二级有明显发热,为什么?

    实际接通后第二级有明显发热。单独测试第一没问题,对第二级直接输入第一的输出相关参数依然正常。可是两块一旦级联第二级就发热。
    发表于 09-06 06:08

    OPA388作为仪表放大,第二级输出总是差点,为什么?

    如图,第二级放大总是比2倍差一点。
    发表于 08-05 08:08

    浪涌保护器和二级浪涌保护器怎么区分

    浪涌保护器和二级浪涌保护器是电力系统中非常重要的保护设备,它们的主要作用是保护电力系统免受雷电、操作过电压等浪涌电压的损害。在电力系统中,浪涌保护器的设置和选择对于系统的安全稳定运行
    的头像 发表于 07-13 14:44 4735次阅读

    二级浪涌保护器型号如何选择

    选择二级浪涌保护器型号时,需要综合考虑多个因素,以确保所选型号能够满足电器系统的实际需求。以下是一些关键步骤和考虑因素: 一、了解系统需求 电压等级 :首先,明确您的电器系统的电压等级,这是选择浪涌
    的头像 发表于 07-13 14:25 733次阅读

    HarmonyOS开发案例:【卡片二级联动】

    使用ArkTS语言,实现一个导航与内容二级联动的效果。
    的头像 发表于 05-06 17:08 521次阅读
    HarmonyOS开发案例:【卡片<b class='flag-5'>二级</b>联动】

    OLED设备公司DMS最近对二级分包商A公司提起诉讼

    WitDisplay消息,OLED设备公司DMS最近对二级分包商A公司提起诉讼,要求支付150亿韩元(8100万元人民币)的过度延误赔偿。
    的头像 发表于 02-29 15:40 680次阅读

    ESD极管是什么?如何选择合适电容值的ESD二级管?

    作为一名关注通信接口和电子元器件的专业人士,你一定对ESD(Electrostatic Discharge)极管非常感兴趣。让我们一起来了解一下ESD极管是什么,以及如何选择合适电容值的ESD二级管吧。
    的头像 发表于 02-21 17:06 2616次阅读
    ESD<b class='flag-5'>二</b>极管是什么?如何选择合适电容值的ESD<b class='flag-5'>二级</b>管?

    二级电源和II电源的区别

    二级电源和II电源的区别 随着电力需求的不断增长,人们对电源的要求也越来越高。二级电源和II电源是两种常见的电源等级,它们在一些关键的技术规范上存在一些区别。 首先,我们来了解一下
    的头像 发表于 01-19 13:51 1934次阅读

    浪涌保护器和二级浪涌保护器的区别是什么?

    浪涌保护器和二级浪涌保护器的区别是什么? 一浪涌保护器和二级浪涌保护器是电气设备中常用的保护装置,用于保护设备免受浪涌电压的影响。浪涌保护器通常被安装在电源线路上,以限制过电压对
    的头像 发表于 01-18 16:22 4050次阅读

    常用二级管的特性及标识

    极管的应用非常广泛,几乎绝大部分电路板上都极管的身影。今天就来讲讲常用二级管特性及标识。
    的头像 发表于 01-11 09:47 1241次阅读
    常用<b class='flag-5'>二级</b>管的特性及标识

    mybatis一缓存和二级缓存的原理

    MyBatis是一种轻量级的持久化框架,它提供了一缓存和二级缓存的机制来优化数据库操作性能。一缓存是默认开启的,而二级缓存需要手动配置启用。 一、一
    的头像 发表于 12-03 11:55 1083次阅读