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

    文章

    4653

    浏览量

    93827
  • 矩阵
    +关注

    关注

    0

    文章

    426

    浏览量

    34773
  • 嵌入式程序
    +关注

    关注

    0

    文章

    6

    浏览量

    6592

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

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

收藏 人收藏

    相关推荐

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

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

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

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

    二级配电箱的作用介绍

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

    物联网系统中如何增强GNSS的信号_GNSS二级放大电路研发测试方案

    01 物联网行业中存在问题 GPS 产品在研发阶段,为优化GNSS产品定位性能,增加射频二级放大电路,需要对产品进行射频测试以及外场实际测试,保证达到提升GNSS产品定位性能,缩短定位时间,从而
    的头像 发表于 09-30 18:25 756次阅读
    物联网系统中如何增强GNSS的信号_GNSS<b class='flag-5'>二级</b>放大电路研发测试方案

    二级和三配电箱的区别

    配电箱作为电能分配与控制的核心设备,发挥着至关重要的作用。根据其在电力系统中的位置和作用不同,配电箱可分为一二级和三。本文将深入探讨这三种配电箱的区别。 一、位置和作用的差异 一
    的头像 发表于 09-20 17:21 3803次阅读

    用两个OPA690接成一个二级饱和放大,出现振铃现象怎么解决?

    用两个OPA690接成一个二级饱和放大,出现振铃现象。两放大都是放大11倍,总共放大121倍,但在不同的频率下,振铃现象会有不同。解决振铃现象的方法有哪些? 下面是示波器单次触发的图片;
    发表于 09-13 07:03

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

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

    用三运放做放大信号,第二级用vca821做可控增益放大,输出波形变了,为什么?

    我用三运放做放大信号第一opa847输出正常,第二级用vca821做可控增益放大,但是输出波形就变了,输入3M;求大师救救我
    发表于 09-11 07:45

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

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

    OPA2333二级放大是否可以实现万倍放大?

    供电电源:直流3.3v 待放大输入电压:10uV。 请问二级放大是否可以实现万倍放大。如果可以,该怎样实现?
    发表于 08-13 06:58

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

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

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

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

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

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

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

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

    华润微电子LX100安全MCU芯片产品荣获商用密码产品二级认证

    近日,华润微电子集成电路(无锡)有限公司LX100安全MCU芯片产品通过国家密码管理局商用密码检测中心安全性审查,符合安全芯片密码检测准则第二级的要求(简称“国密二级”),获得由国家密码管理局商用密码检测中心颁发的《商用密码产品认证证书》。
    的头像 发表于 04-11 14:40 1741次阅读
    华润微电子LX100安全MCU芯片产品荣获商用密码产品<b class='flag-5'>二级</b>认证