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

    文章

    4459

    浏览量

    90838
  • 矩阵
    +关注

    关注

    0

    文章

    406

    浏览量

    34256
  • 嵌入式程序
    +关注

    关注

    0

    文章

    6

    浏览量

    6507

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

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

收藏 人收藏

    评论

    相关推荐

    怎么理解指针指针

    怎么理解指针指针?其实这个概念并不难,只是把它放到实际应用中,容易造成困扰。
    的头像 发表于 02-23 16:46 416次阅读
    怎么理解<b class='flag-5'>指针</b>的<b class='flag-5'>指针</b>?

    LT8331把二级升压电路去掉,上电瞬间LT8331升压器SW1和SW2引脚与GND短路是怎么回事?

    按照参考电路设计,想把24V电压升压到240V,测了输出只有24V。我把二级升压电路去掉,上电瞬间LT8331升压器SW1和SW2引脚与GND短路,是怎么回事?电路元器件参数按照参考电路设计来设计的
    发表于 01-04 07:52

    函数指针指针函数是不是一个东西?

    函数指针的本质是指针,就跟整型指针、字符指针一样,函数指针指向的是一个函数。
    的头像 发表于 01-03 16:35 267次阅读
    函数<b class='flag-5'>指针</b>和<b class='flag-5'>指针</b>函数是不是一个东西?

    AD8421用于第二级放大的时候是不是很容易就饱和了?

    请问大神,对于三运放仪用放大器芯片AD8421,把它用于第二级放大的时候,前一的两个放大器输出的共模电压达到AD8421的工作电源的时候,AD8421是不是很容易就饱和了?
    发表于 11-27 08:00

    将两个AD8367联使用时,第一的输出与第二级的输入之间是否还需要加匹配网络呢?

    将两个AD8367联使用时,第一的输出与第二级的输入之间是否还需要加匹配网络呢?根据手册上的描述,输出RL时200欧姆,而AD8367的输入也是200欧,那么是否可以不用匹配而直接将第一
    发表于 11-27 07:50

    指针是什么

    指针是什么? 1.1 浅谈指针 理解指针的 两个要点: 指针是内存中一个最小单元的编号,也就是地址; 平时口语中说的指针,通常指的是
    的头像 发表于 11-24 15:50 1292次阅读
    <b class='flag-5'>指针</b>是什么

    使用的ADA4895-2芯片在放大时第二级会有一个1V左右的直流偏置是为什么?

    ADI的工程师,您好,我想问一下我使用的ADA4895-2芯片在放大时第二级会有一个1V左右的直流偏置,请问一下是怎么回事。是反馈电阻选的不对还是放大倍数一定要10倍以上
    发表于 11-21 08:31

    使用ADA4817制作二级宽带放大器,输出信号会逐渐变为全负是什么原因?

    使用ADA4817制作二级宽带放大器。输入信号为正弦波,幅度有效值为10mV-1V,频率为1Hz-100MHz。第一放大倍数为3.6倍,第二级放大倍数为3.6倍,间做一倍衰减,因此
    发表于 11-17 14:09

    C语言中数字怎么转成指针

    C语言中数字怎么转成指针,比如我要去内存地址为0x100的内容,用一句话表达,不如uchar a=?我要问号等于0x100地址的内容
    发表于 10-31 06:29

    C51中的函数指针

    函数指针C编程语言的许多困难特性之一。 由于C编译器对8051体系结构的独特要求,函数指针和可重入函数面临着更大的挑战。 这主要是由于传递函数参数的方式所致。 通常,(对于除8051
    发表于 09-04 08:29

    C语言中指针数组和数组指针的区别

    指针和数组之间存在着紧密的关系。在本文中,我们将探讨指针和数组的关系、指针算术和数组遍历、多维数组与指针以及指针数组和数组
    发表于 08-17 15:29 282次阅读

    C语言中空指针和野指针的概念及产生原因

    在C语言中,指针是一种非常强大和灵活的工具,但同时也容易引发一些问题,其中包括空指针和野指针
    发表于 08-16 16:18 404次阅读

    贴片极管S27是哪一种二级

    贴片极管S27是哪一种二级管有哪位大神知道请回复
    发表于 06-20 09:39

    C语言中一级指针二级指针和三级指针

    一级指针的用法其实是取数据的地址,以此类推,二级指针就是取一级指针的地址,也可以表示一级指针的指向的内容。
    发表于 05-19 17:30 958次阅读
    C语言中一级<b class='flag-5'>指针</b>、<b class='flag-5'>二级</b><b class='flag-5'>指针</b>和三级<b class='flag-5'>指针</b>