1
int a[3][3]={5};
printf("&a = %u \n a = %u \n*a = %u\n&a[0][0]=%d\na[0][0]", &a, a, *a, &a[0][0], a[0][0]);

输出:-

&a = 2359028
 a = 2359028
*a = 2359028
&a[0][0]=2359028
a[0][0] =5

这些怎么可能都一样?如果 a=2359028 的值,那么不应该*a在地址 2359028 即 5 处给出值吗?

4

3 回答 3

5
  1. &a给你数组的地址。它的类型int (*)[3][3]。简单的。

  2. a表示数组本身,并将进行数组到指针的转换,成为指向数组第一个元素的指针。数组的第一个元素是一个类型为 的子数组int[3],所以我们得到一个指向该子数组的指针。该指针的类型为int (*)[3]。这与以前的地址相同,因为第一个子数组位于数组的开头。

  3. 使用*a,数组再次进行数组到指针的转换,以获得与以前相同的指向子数组的指针。然后取消引用以获取子数组本身。然后这个表示子数组的表达式也进行数组到指针的转换,给你一个指向它的第一个元素的指针。第一个元素是 type int,所以指针是 type int*。第一个元素的地址与它所在的子数组的地址相同,正如我们所见,它与整个数组的地址相同。

  4. &a[0][0]首先获取第一个子数组的第一个元素,然后获取它的地址。这为您提供了与前一点完全相同的指针。

因此,所有这些指针都具有相同的值。

图解:

  0,0   0,1   0,2   1,0   1,1   1,2   2,0   2,1   2,2
┌─────┬─────┬─────┬─────┬─────┬─────┬─────┬─────┬─────┐
│ int │ int │ int │ int │ int │ int │ int │ int │ int │
└─────┴─────┴─────┴─────┴─────┴─────┴─────┴─────┴─────┘

└─────────────────────────────────────────────────────┘
            &a points at the entire array

└─────────────────┘
  a gives you a pointer to the first subarray

└─────┘
  *a gives you a pointer to the element 0,0
  and so does &a[0][0]

这些区域都从相同的地址开始,因此指针具有相同的值。

于 2013-05-09T15:35:46.570 回答
0

“......不应该 *a 在地址 2359028 即 5 处给出值吗?”

是和不是。*a确实应该在 address给你对象a。但是,在您的情况下a有 type int[3][3]。这意味着在这个间接级别上,地址处的对象a(如果我们将其解释a为指针)并不5像您错误地认为的那样,它实际上是整个一维数组a[0]*ais的类型int [3]和存储的值*a同样是整个 1D subarray a[0]

因此,当您尝试 时printf *a,实际上是在将整个a[0]子数组指定为参数。该子数组衰减为指针,该指针自然指向相同的位置(因为整个数组a及其第一个子数组a[0]在内存中具有相同的位置)。这就是为什么打印a*aas 指针(以及&a)会导致打印相同的数值。

如果你想5在这种情况下访问,你必须这样做**a。只是*a还不够。

于 2013-05-09T15:49:28.923 回答
0

在 C 语言中,当数组涉及到表达式时(例如,当传递给函数或指针算术时),它会隐式转换为指针。因为您要传递aprintf,所以它被隐式转换为指向 的指针a,这与&a.

*a您可能会对看起来像相对于 的双重取消引用的事实感到困惑&a,它返回了数组的地址,因此*a这种逻辑应该导致a[0][0]. 但事实并非如此。

于 2013-05-09T15:36:27.680 回答