• C语言中的 int** 是什么?这要从int* 和int 说起...


    文章来源:https://yian.me/blog/what-is/pointer-to-pointer-in-c-programing-language.html?utm_source=tuicool&utm_medium=referral

    作者: Y!an

    从int* 和int 说起

    “int** 是什么” 这个问题其实不难。

    我们可以递归分析,先看下int* 是什么,嗯?好像还可以继续递归到int

    我们都知道,int 是 C 的基础数据类型整型 ,而多了个* 的int* 是指向整型变量的指针,那么int** 是什么就不言自明了,列个表:


     

    看到这里,你对int**应该有了个初步的认识,但你可能觉得有点绕,没关系,下面我们写一段代码看看:

    #include <stdio.h>

    int main()

    {

        int i = 418;

        int* pi;

        // 根据上面的表格,我们知道 int* 是指向“整型”的指针,

        // 那么 pi 可以保存的是 int 类型的变量 i 的地址:

        pi = &i;

        int** ppi;

        // ppi 可以保存的是 int* 类型的变量 pi 的地址:

        ppi = π

        // 恭喜你,现在你已经知道了怎么定义 int** 类型的变量和给它赋值

        // 我们先写到这里

        return 0;

    }

    深入思考

    假如定义有int** p(为了方便,我们暂且把p认为是ppi的别名),那么p,*p,**p,p + 1,*p + 1,*(p + 1),**p + 1,*(*p + 1),**(p + 1)分别是什么?

    先看最指针自身

    乍一看有点多,开始有点慌是吧,没关系,我们先看不带加法运算的前三个:p,*p以及**p

    从上面的代码我们已经知道p就是存放int*类型变量的地址的变量

    // 从上面暂停下来的地方我们继续

        // 我们都知道,在指针前面加个 * 就是“取得这个指针指向的地址里的值”

        // 因为 pi 存放的是 i 的地址,那么 *pi 就是取得 i 存放的值,类型是 int

        // 同理,*ppi 取得的是 pi 存放的值,类型是 int*

        printf("*pi = %d, *ppi = %p ", *pi, *ppi);

        // 输出 *pi = 418, *ppi = 0000002D6FF2FD58 (*pi = 后面的值在每台机器上都可能不一样)

        // 既然 *ppi 是 int*,那也就是说我们还可以对它再做一次解引用,

        // 拿到 *ppi 这个地址里存放的值,类型是 int

        printf("**ppi = %d ", **ppi);

        // 输出 **pi = 418

    这时,你已经掌握p,*p以及**p分别是什么了

    再看指针的加法运算

    接下来我们还是先挑最简单的,把不带*的拿出来:p + 1,指针p做了个加法运算。

    那么它加的这个1是什么?数字1?1位?1字节?

    都不是,C指针加法运算里的数字操作数的单位是指针的长度,也就是说p + 1表示的时候内存中,紧挨着p的下一个可用空间的地址:

    printf("ppi = %p, ppi + 1 = %p ", ppi, ppi + 1);

        // 输出 ppi = 0000008CA96FFB78, ppi + 1 = 0000008CA96FFB80

        // 并且我们可以看到 0000008CA96FFB80 - 0000008CA96FFB78 = 8(16进制)

        // 恰好等于 x64 系统下 1 个指针的大小:8 字节

    那*(p + 1)是什么你应该也知道了,就是p + 1这个地址(假设是合法的)存放的值,类型是int*。

    而*p + 1就是*p这个地址再偏移了 1 个指针长度

    printf("*ppi = %p, *ppi + 1 = %p ", *ppi, *ppi + 1);

        // 输出 *ppi = 0000002D6FF2FD58, *ppi + 1 = 0000002D6FF2FD60

        printf("pi = %p ", pi);

        // 输出 pi = 0000002D6FF2FD58

        // 可以看到 *ppi == p

    好了,还剩下最后三个:**p + 1,*(*p + 1),**(p + 1),先试试结合上面的知识,想一下在我们的例子中这三个分别是什么,想好之后再看下面的答案检验一下自己理解得对不对:

    **p + 1:**p取得的是int,值是 418,所以**p + 1是 419

    *(*p + 1):*p + 1是0000002D6FF2FD60,那么*(*p + 1)就是取得这个地址中的值(假设地址都是合法的)

    **(p + 1):先对p + 1这个地址做解引用,得到新的地址*(p + 1),然后再对新的地址做解引用,得到的是个int(假设地址都是合法的)

    再给你int***你也能回答了

    现在再给你int***,相信你也知道它是什么并且知道它相关的运算是什么了:


     

    最后

    特别推荐一个分享C/C++和算法的优质内容,学习交流,技术探讨,面试指导,简历修改...还有超多源码素材等学习资料,零基础的视频等着你!

    还没关注的小伙伴,可以长按关注一下:


     
  • 相关阅读:
    【思考题】任意长度有理数乘法运算
    【排序】表插入排序算法(C语言版)
    JAVA中的反射
    JAVA中关于日期的最常见的操作
    Hibernate:基于HQL实现数据查询
    Hibernate与Mybatis对比
    使用idea实现SSM框架整合
    基于maven搭建hibernate运行环境
    MYSQL中的存储过程
    MySQL 索引
  • 原文地址:https://www.cnblogs.com/mu-ge/p/14476517.html
Copyright © 2020-2023  润新知