令人惊讶的指针

时间:2010-10-13 23:16:30

标签: c arrays pointers

我很惊讶地看到这个代码段为所有三个指针打印相同的地址。

int main(int argc,char *argv[])
{
   int arr[3][3];
   printf("%p\n%p\n%p\n",arr,*arr,arr[0]);
   return 0;
}

为什么会这样?

4 个答案:

答案 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

与所有C指针一样

*arr = arr[0]

基本上它们都是一样的,因为C放置多维数组的方式,数组开头的地址也是数组第一行的地址。

这种混淆的一部分是,对于一维数组,arr[]arr可以被视为指针,就像它被定义为'* arr'一样。对于多维数组而言,情况并非如此。 arr[][]不能被视为双指针,就好像它被定义为**arr一样。它们是非常不同的数据类型。