当前位置:首页 > 公众号精选 > 嵌入式微处理器
[导读]1、先把问题摆出来 参考Demo: 1#include  2#include  3 4/************************************ 5 * Fuction: 测试demo  6 * Author :(公众号:最后一个bug)  7 ***********************************/ 8int main(int argc, char *argv[


1、先把问题摆出来


参考Demo:
 1#include <stdio.h>
2#include <stdlib.h>
3
4/************************************
5 * Fuction: 测试demo 
6 * Author :(公众号:最后一个bug) 
7 ***********************************/

8int main(int argc, char *argv[]) {
9    int a = 10;
10    int *ptr = &a;
11    int **ptrptr = &ptr;
12
13    printf("           *ptr = %d\n",*ptr);
14    printf("       **ptrptr = %d\n",**ptrptr);
15    printf("**((int **)ptr) = %d\n",**((int **)ptr));
16    printf("欢迎关注公众号:最后一个bug\n"); 
17    return 0;
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 <stdio.h>
2#include <stdlib.h>
3/************************************
4 * Fuction: 测试demo 
5 * Author :(公众号:最后一个bug) 
6 ***********************************/

7int main(int argc, char *argv[]) {
8    int a = 10;
9    int *ptr = &a;
10
11    printf(" a   = %d\n",a);
12    printf("&ptr = 0x%X\n",&ptr);
13    printf("&a   = 0x%X\n",&a);
14    printf("ptr  = 0x%X\n",ptr);
15    printf("*ptr = %d\n",*ptr);
16
17    printf("欢迎关注公众号:最后一个bug\n"); 
18    return 0;
19}
运行结果:

图解:

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

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

3

二级指针
    如果大家已经理解了一级指针,二级指针也就顺理成章了,来看看下面的小程序:
Demo:
 1#include <stdio.h>
2#include <stdlib.h>
3/************************************
4 * Fuction: 测试demo 
5 * Author :(公众号:最后一个bug) 
6 ***********************************/

7int main(int argc, char *argv[]) {
8    int a = 10;
9    int *ptr = &a;
10    int **ptrptr = &ptr;
11
12    printf(" a      = %d\n",a);
13
14    printf("&ptrptr = 0x%X\n",&ptrptr);
15
16    printf("ptrptr  = 0x%X\n",ptrptr);
17    printf("&*ptrptr= 0x%X\n",&*ptrptr);
18    printf("&ptr    = 0x%X\n",&ptr);
19
20    printf("*ptrptr = 0x%X\n",*ptrptr);
21    printf("ptr     = 0x%X\n",ptr);
22
23    printf("*ptr    = %d\n",*ptr);
24    printf("**ptrptr= %d\n",**ptrptr);
25
26    printf("欢迎关注公众号:最后一个bug\n"); 
27    return 0;
28}
运行结果:

图解:

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

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

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

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


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

参考Demo:
 1#include <stdio.h>
2#include <stdlib.h>
3
4/************************************
5 * Fuction: 测试demo 
6 * Author :(公众号:最后一个bug) 
7 ***********************************/

8int main(int argc, char *argv[]) {
9    int a = 10;
10    int *ptr = &a;
11    int **ptrptr = &ptr;
12
13    printf("           *ptr = %d\n",*ptr);
14    printf("       **ptrptr = %d\n",**ptrptr);
15    printf("**((int **)ptr) = %d\n",**((int **)ptr));
16    printf("欢迎关注公众号:最后一个bug\n"); 
17    return 0;
18}
分析一下:
  • 我们知道问题出在**(int**)ptr,不太理解的小伙伴总是觉得,我已经强制类型转化为二级指针了,前面只需要用**获得最后的值即可,怎么就不行呢? 我知道这里有问题我就是不理解为什么?

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


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

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

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


4、最后小结


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

  


-END-


本文授权转载自公众号最后一个bug,作者:bug菌




推荐阅读



【01】GitHub新功能:发起抗议「996」,一小时获1000星
【02】为什么美国程序员工作比中国程序员工作轻松、加班少?
【03】在华为,加班究竟有多恐怖?
【04】按照这个代码调试指南,别人加班你下班!
【05】京东强推 995 工作制,中国式变态加班何时休?


免责声明:整理文章为传播相关技术,版权归原作者所有,如有侵权,请联系删除

免责声明:本文内容由21ic获得授权后发布,版权归原作者所有,本平台仅提供信息存储服务。文章仅代表作者个人观点,不代表本平台立场,如有问题,请联系我们,谢谢!

嵌入式ARM

扫描二维码,关注更多精彩内容

本站声明: 本文章由作者或相关机构授权发布,目的在于传递更多信息,并不代表本站赞同其观点,本站亦不保证或承诺内容真实性等。需要转载请联系该专栏作者,如若文章内容侵犯您的权益,请及时联系本站删除。
关闭
关闭