2D数组:当我将ptr声明为int ptr [4] [4]时,为什么ptr和* ptr相同?

Don*_*ong 1 c arrays pointers

我正在测试一些代码,以了解如何在c中实现2d数组。然后我遇到了以下问题。

代码是:

int main(){
   int a[4][4];
   printf("a: %p, *a: %p, **a: 0x%x\n",a,*a,**a);
}
Run Code Online (Sandbox Code Playgroud)

我用32位ubuntu gcc编译了这个

结果是:

a:0xbf9d6fdc,* a:0xbf9d6fdc,** a:0x0

我期望a和的值不同*a,但是它们是相同的。

  1. 为什么a*a在这种情况下相同?是不是a一个int**类型?

  2. 那么,*操作员的作用是什么*a

Sou*_*osh 7

检查类型!

给定的定义为 int a[4][4];

  • a是类型int [4][4]-由4个整数组成的数组的数组。这是一样的int **
  • a[n]是类型int [4]-4个整数的数组。这是一样的int *
  • a[n][m]是类型int。- 整数。

现在,鉴于事实,即数组的地址也是数组中第一个元素的地址,值是相同的,但是它们的类型不同。

目视检查

int a[4][4]

      +-------+--------+-------+-----------+
      |       |        |       |           |
      |a[0][0]| a[0][1]| a[0][2]   a[0][3] |
      |       |        |       |           |
      +------------------------------------+
      |       |        |       |           |
      |a[1][0]|        |       |           |
      |       |        |       |           |
      +------------------------------------+
      |       |        |       |           |
      |a[2][0]|        |       |           |
      |       |        |       |           |
      +------------------------------------+
      |       |        |       |           |
      |       |        |       |           |
      |       |        |       |           |
      |       |        |       |           |
      +-------+--------+-------+-----------+
Run Code Online (Sandbox Code Playgroud)

然后,引用C11§6.3.2.1

除非它是运算sizeof符,_Alignof运算符或一元运算&符的操作数,或者是用于初始化数组的字符串文字,否则类型为“ array of type”的表达式将转换为类型为“''的表达式类型指针''指向数组对象的初始元素,不是左值。[...]

因此,在将类型为array的参数作为函数参数传递时,它会衰减到指向数组第一个元素的指针。

所以,让我们看一下。

  • a,衰减为&(a[0])-类型的第一个元素的地址int (*)[4]
  • *a与相同a[0],会衰减为int *第一个元素的指针。
  • **a*(*a)== *(a[0])== 相同a[0][0]-这是该int索引处的值。

现在,再次仔细看看上面的图片-你看到的第一个元素int [0]int [0][0]基本都居住在同一地址?换句话说,起始地址是相同的。

这就是您看到的输出背后的原因。