我很惊讶地看到这个代码段为所有三个指针打印相同的地址。
int main(int argc,char *argv[])
{
int arr[3][3];
printf("%p\n%p\n%p\n",arr,*arr,arr[0]);
return 0;
}
为什么会这样?
答案 0 :(得分:4)
请参阅So what is meant by the ``equivalence of pointers and arrays'' in C?
数组的地址是其第一个元素的地址。而且,对于任何数组arr[i]
,*(arr + i)
相当于arr
。因此,arr[0]
与*(a + 0)
相同。
答案 1 :(得分:3)
因为数组的地址等于起始元素的地址。
这意味着,arr[1]
的地址等于arr + 1
的地址和*(arr + 1)
的地址。
答案 2 :(得分:3)
C将多维数组展平 - 因此int[3][3]
实际上只是和int[9]
数组在内存中 - 只有类型不同。 / p>
因此,由于在大多数表达式中使用数组时,数组被静默转换为指向其第一个元素的指针*arr
总是等于所有数组的arr [0]。
在这个例子中,arr
(两个间接到int的级别)是指向第一个int[3]
数组的指针,*arr==arr[0]
(1个间接到int的级别)是指向第一个整数的指针在第一个int[3]
数组中,由于整个结构是“平坦的”,因此第一个int[3]
始于与int[3][3]
数组完全相同的位置。
它有点令人困惑,但在内存中,连续只有9个整数,编译器'知道'应该被视为3个块
如果细胞如下所示:
|0|1|2|3|4|5|6|7|8|
然后arr
是指向| 0 |的指针,arr+1
是指向| 3 |的指针arr+2
是指向| 6 |
arr[0]
也是指向| 0 |的指针,arr[0]+1
是指向| 1 |的指针,arr[0]+2
是指向| 2 |的指针。等等...
由于arr[0]
对于任何数组始终与*arr
相同,因此*arr
也是指向| 0 |
答案 3 :(得分:1)
arr
是数组中第一个元素的地址,它也是数组第一行的地址,因为C在内存中放置了多维数组。
arr[0]
返回指向第一行的指针,因此等同于arr
*arr
= arr[0]
基本上它们都是一样的,因为C放置多维数组的方式,数组开头的地址也是数组第一行的地址。
这种混淆的一部分是,对于一维数组,arr[]
,arr
可以被视为指针,就像它被定义为'* arr'一样。对于多维数组而言,情况并非如此。 arr[][]
不能被视为双指针,就好像它被定义为**arr
一样。它们是非常不同的数据类型。