c语言二维数组指针长度问题

第一个输出能理解,就是4乘6;为什么后面的输出全是8,加1的时候难道不是5乘4吗,有没有人能解释一下,多谢了

#include<stdio.h>

int main(){

int a[2][6] = 
{10,20,30,40,50,60,
70,80,90,100,110,120};
int (*p)[6] =a;            
 printf("%d\n",sizeof(*(p+1)));  
printf("%d\n",sizeof(*(p+1)+1));
 printf("%d\n",sizeof(*(p+1)+2));
  printf("%d\n",sizeof(*(p+1)+3));
printf("%d",sizeof(*(p+1)+8));
return 0;

}

img

第一个输出的相当于将二维数组a[2][6] 转换成一维数组的大小sizeof(a[1]) = 24
第二个开始,输出的是一个指针的大小,你的系统得到 8 ,说明是64位的。

*(p+1)本来是个地址
但是你强行在地址上+1,它的类型变了,变成ulong了

  • 你可以看下这个问题的回答https://ask.csdn.net/questions/7722557
  • 你也可以参考下这篇文章:C语言6习题9 有15个数按由大到小顺序存放在一个数组中,输入一个数,要求用折半查找法找出该数是数组中第几个元素的值。如果该数不在数组中,则输出无此数
  • 除此之外, 这篇博客: 【C语言数组】一维数组,二维数组详解,数组传参,变长数组,这篇文章让你更全面的认识数组。中的 🧨2.4.1 内存图演示 部分也许能够解决你的问题, 你可以仔细阅读以下内容或跳转源博客中阅读:
  • 从下图我们可以了解到,二维数组也是连续存放的,但为了有视觉体验,我们做题的时候还是行列分开进行分析,内存中的布局我们了解即可,平时使用就按照行和列分开进行。

    在这里插入图片描述

  • 您还可以看一下 李飞老师的C语言开发之数据结构与算法二课程中的 树的深度遍历(非递归)小节, 巩固相关知识点
  • 以下回答由chatgpt基于相关博客总结生成:

    首先,关于C语言二维数组指针长度的问题,可以从内存布局的角度来解释。

    首先我们需要了解一维数组和二维数组的内存布局。

    对于一维数组a[N]来说,因为每个元素的大小相同,所以我们可以根据元素的类型和数组的长度来计算出需要的内存大小。因此,a[N]的长度就是sizeof(a[0]) * N。

    对于二维数组a[M][N]来说,内存是一维连续的。假设a的地址是p,则a[0]的地址是p,a[1]的地址是p + N * sizeof(a[0]),以此类推。因此,a[M]的长度就是sizeof(a[0]) * N * M。

    现在我们来解释为什么第一个输出是4乘6,而后面的输出全都是8。

    假设我们有一个二维数组int a[4][6],它的地址是p,则a[0]的地址是p,a[1]的地址是p + 6 * sizeof(int),以此类推。

    对于int类型的指针,它是一个指向指针的指针,也就是说它指向的是一个一维数组。所以它的大小是sizeof(int*)。因此,int类型的指针p的长度就是sizeof(int*)。

    对于二维数组int a[4][6],我们可以将它看作是一个指向指针的指针int*,因为a是一个指针,a[i]也是一个指针。所以a的长度就是sizeof(int)。

    所以第一个输出是4乘6,是因为二维数组的第一维的长度是4,第二维的长度是6。

    而后面的输出全都是8,是因为二维数组的内存布局是一维连续的。对于int*类型的指针来说,它指向的是一个一维数组,而一维数组的长度就是sizeof(int)。所以后面的输出全都是8。

    综上所述,第一个输出是4乘6,后面的输出全都是8。

    如果你还有其他问题或需要更详细的解释,请告诉我。