• C语言基础知识点(六)二维数组指针和地址


    1. #include
    2. int main()
    3. {
    4. int a[2][3] = {
    5. 2, 4, 6,
    6. 8, 10, 12};
    7. printf("a:%p, a+1:%p\n", a, a + 1); // 相差3*sizeof(int)=12,二维数组名是一个指向每一行的指针,a:0061FF08, a+1:0061FF14
    8. printf("&a:%p, &a+1:%p\n", &a, &a + 1); // 相差6*sizeof(int)=1224,&a:0061FF08, &a+1:0061FF20
    9. printf("a[0]:%p, a[0]+1:%p\n", a[0], a[0] + 1); // 相差一个sizeof(int)也就是一个数更多v组元素,a[0]:0061FF08, a[0]+1:0061FF0C
    10. printf("&a[0]:%p, &a:%p\n", &a[0], &a); // 结果一样,&a[0]:0061FF08, &a:0061FF08
    11. printf("&a[0]+1:%p, &a+1:%p\n", &a[0] + 1, &a + 1); //&a[0]跳了12个字节(跳过了一行),而&a跳了24个字节(跳过了整个二维数组)
    12. printf("*a:%p, *a+1:%p,*(a+1):%p\n", *a, *a + 1, *(a + 1)); /* a:0061FF08, *a+1:0061FF0C,*(a+1):0061FF14
    13. *a+1偏移了一个sizeof(int).*(a+1)偏移了一行 */
    14. printf("**a:%p, **a+1:%p,**(a+1):%p\n", **a, **a + 1, **(a + 1));
    15. printf("*a[0]:%p, *a[0]+1:%p,*(a[0]+1):%p\n", *a[0], *a[0] + 1, *(a[0] + 1));
    16. printf("*a[1]:%p, *a[1]+1:%p,*(a[1]+1):%p\n", *a[1], *a[1] + 1, *(a[1] + 1));
    17. }
    1. printf("a:%p, a+1:%p\n", a, a + 1);

      输出结果:a:0061FF08, a+1:0061FF14 解释:a是指向二维数组第一行的指针,a+1是指向二维数组第二行的指针。每行有3个int元素,所以相差3个sizeof(int)字节,即12个字节。

    2. printf("&a:%p, &a+1:%p\n", &a, &a+1);

      输出结果:&a:0061FF08, &a+1:0061FF20 解释:&a是整个二维数组的地址,&a+1是整个二维数组后面的地址。整个二维数组占用了2行3列,总共有6个int元素,所以相差6个sizeof(int)字节,即24个字节。

    3. printf("a[0]:%p, a[0]+1:%p\n", a[0], a[0]+1);

      输出结果:a[0]:0061FF08, a[0]+1:0061FF0C 解释:a[0]是二维数组的第一行,是指向第一个元素的指针。每个元素占用一个sizeof(int)字节,所以相差一个sizeof(int)字节。

    4. printf("&a[0]:%p, &a:%p\n",&a[0], &a);

      输出结果:&a[0]:0061FF08, &a:0061FF08 解释:&a[0]是二维数组的第一行的地址,与&a相同,都是指向二维数组第一行的指针。

    5. printf("&a[0]+1:%p, &a+1:%p\n",&a[0]+1, &a+1);

      输出结果:&a[0]+1:0061FF14, &a+1:0061FF20 解释:&a[0]+1跳过了一行,相当于指向了第二行的地址;&a+1跳过了整个二维数组,指向了整个二维数组后面的地址。

    6. printf("*a:%p, *a+1:%p,*(a+1):%p\n",*a, *a+1,*(a+1));

      输出结果:*a:0061FF08, *a+1:0061FF0C,*(a+1):0061FF14 解释:*a是指向第一行的指针,解引用后得到第一行的第一个元素;*a+1偏移了一个sizeof(int)字节,即指向第一行的第二个元素;*(a+1)是指向第二行的指针,解引用后得到第二行的第一个元素。

    7. printf("**a:%p, **a+1:%p,**(a+1):%p\n",**a, **a+1,**(a+1));

      输出结果:**a:00000002, **a+1:00000003,**(a+1):00000008 解释:**a是指向第一行的指针,解引用两次后得到第一行的第一个元素;**a+1对第一行的第一个元素加1;**(a+1)是指向第二行的指针,解引用两次后得到第二行的第一个元素。

    8. printf("*a[0]:%p, *a[0]+1:%p,*(a[0]+1):%p\n",*a[0], *a[0]+1,*(a[0]+1));

      输出结果:*a[0]:00000002, *a[0]+1:00000003,*(a[0]+1):00000004 解释:*a[0]是第一行的第一个元素,解引用后得到该元素的值;*a[0]+1加上1;*(a[0]+1)是第一行的第二个元素,解引用后得到该元素的值。

    9. printf("*a[1]:%p, *a[1]+1:%p,*(a[1]+1):%p\n",*a[1], *a[1]+1,*(a[1]+1));

      输出结果:*a[1]:00000008, *a[1]+1:00000009,*(a[1]+1):0000000A 解释:*a[1]是第二行的第一个元素,解引用后得到该元素的值;*a[1]+1加上1;*(a[1]+1)是第二行的第二个元素,解引用后得到该元素的值。

    涉及到了指针和数组的相关知识点,以下是一些总结:

    1. 指针与地址:指针是存储内存地址的变量,可以通过加/减整数来进行地址运算。&运算符用于获取一个变量的地址。

    2. 数组与指针:数组名可以看作是指向数组第一个元素的指针。对于二维数组,每一行都可以看作是指向该行第一个元素的指针。使用a[i]*(a+i)来访问数组元素。

    3. 指针运算:指针运算的结果取决于指针类型和操作数的类型。对指针进行加/减操作时,会根据指针所指向类型的大小进行相应的偏移。

    4. 解引用操作符:使用*运算符可以解引用指针,获取指针所指向的值。

    5. printf格式化输出:%p用于打印指针地址的值。

    二维数组名指向行的,“&二维数组名”就指向了整个二维数组"二维数组名[i]" 是指向i行的首元素的地址·。“&二维数组名[i]”就指向了一行

    在C语言中,数组名是一个指向数组第一个元素的指针,即其本身代表了该数组第一个元素的地址。因此,在使用数组名时,可以将其视为指向数组第一个元素的指针,例如a[i]就是指向二维数组第i行第一个元素的指针。

    对于二维数组而言,&a[i]表示的是二维数组的第i行的地址,但由于数组名已经代表了该数组第一个元素的地址,所以a[i]&a[i]其实是等价的,它们所代表的值也相同。

    *二维数组名[i]就是取出第i行首元素的值,

    *二维数组名[i]+1就是对取出第i行首元素的值进行+1,

    *(二维数组名[i]+1)就是对取出第i+1行首元素的值进行+1

  • 相关阅读:
    LeetCode每日一练 —— CM11 链表分割
    Spring的事件机制
    ES(二)| 安装ES、Kibana、IK分词器、拼音分词器(自动补全)
    【Linux】权限管理 _目录权限 _umask _粘滞位[学习总结 _复习专用]
    Java构件技术
    Python txt文件转成xlsx文件
    Jmeter排查正则表达式提取器未生效问题
    破局DevOps|8大北极星指标指引研发效能方向
    Linux安装Redis操作
    JXLS 导出多sheet,带页眉页脚
  • 原文地址:https://blog.csdn.net/qq_51519091/article/details/132911841