#include <stdio.h>
int main(void){
int arr[][2] = {1,2,3,4};
printf("0x%p\n", arr);
printf("0x%p\n", *arr);
return 0;
}
答案 0 :(得分:9)
数组会衰减为它们的第一个元素的指针。
因此,当您打印arr
时,实际上是&arr[0]
。
当您打印*arr
时,实际上是&arr[0][0]
。
两者都从同一位置开始。
很容易看出我们是否查看数组在内存中的状态:
+-----------+-----------+-----------+-----------+ | arr[0][0] | arr[0][1] | arr[1][0] | arr[1][1] | +-----------+-----------+-----------+-----------+ ^ | &arr[0][0] | &arr[0] | &arr
不同指针之间的最大区别不是它们的位置,而是它们的类型:&arr[0][0]
的类型为int *
; &arr[0]
的类型为int (*)[2]
;并且&arr
的类型为int (*)[2][2]
。
当处理这些问题时,知道对于任何数组或指针a
和索引i
,表达式a[i]
精确地等于 也很有帮助。 *(a + i)
。
如果我们采用例如&arr[0]
等于&(*(arr + 0))
。等于&(*arr)
等于arr
(因为运算符&
和解引用运算符*
的地址相互抵消)。
如上所述,arr[0]
也等于0[arr]
。这也来自arr[i]
和*(arr + i)
的等效项。
由于添加了commutative property,表达式*(arr + i)
等于*(i + arr)
,因此导致了奇数i[arr]
语法。
这是一种好奇心,不应使用“真实”代码来完成。
答案 1 :(得分:1)
arr
是一个数组,因此当在表达式中使用它时,它的值将是指向第一个元素的指针。
类似地,*arr
也是一个数组,因此它也被转换为指向第一个元素的指针。
值相同是因为数组的地址与它的第一个元素的地址相同,尽管类型不同。