(arr + 2)等效于*(arr + 2)。怎么样?

时间:2018-08-28 16:40:17

标签: c arrays pointers

我正在研究如何在指针的帮助下显示2D数组的元素。这是我尝试的代码:

#include<stdio.h>  

int main(){

    int arr[3][2] = {  

    {7, 8},
    {6,3},
    {3,4}
    };

    printf("%u\n", (arr + 2));
    printf("%u\n", *(arr + 2)); 
}

输出:

6487616
6487616

我期望*(arr + 2)的输出为3。与(arr + 2)有什么区别?

3 个答案:

答案 0 :(得分:14)

2D数组实际上是数组的数组。

表达式arr + 2的类型为int (*)[2],而*(arr + 2)的类型为int [2]。在打印前者时,您有一个指针,以便打印指针的值。在后一种情况下,您有一个数组,该数组会衰减为指向第一个元素的指针。因此*(arr + 2)衰减为arr + 2,与第一个表达式相同。

要进一步了解arr + 2arr的类型为int [3][2]。当您向其添加整数值时,它会衰减为指向第一个成员的指针,因此arr会衰减为类型int (*)[2],并且arr + 2也具有该类型,并指向子数组包含{ 3, 4 }

还要注意,指针应使用%p格式说明符打印,并且指针必须强制转换为void *,否则将调用undefined behavior。在这种情况下,您“很幸运”他们碰巧打印了同样的东西。

要获得您期望的3的输出,您需要再取消引用一次:

*(*(arr + 2))

答案 1 :(得分:3)

arrint的数组的数组。几乎在任何使用情况下,数组都将转换为指向其第一个元素的指针。因此arr被转换为指向int数组的指针。

好的,arr被转换为指向int的数组的指针,所以(arr+2)的类型相同,即指向{{1}的数组的指针}。

现在int就是*(arr+2)所指的东西。也就是(arr+2)的数组。

现在,由于它是int的数组,因此将其转换为指向其第一个元素的指针。因此int被转换为指向*(arr+2)的指针。请注意,它不是int的,并且不可能等于int

现在3(arr+2)的dosplay为何相同?它们是指向数组的指针,并且是指向第一个元素的指针。尽管这些指针的类型不同,但是它们表示相同的地址,因为任何数组的地址都与其第一个元素的地址相同。

答案 2 :(得分:1)

arr是指向类型int[2]的第一个数组的指针。(arr + 2)是指向这样的第三个数组的指针。
*(arr + 2)是指向(arr +2)数组第一个元素的指针。
由于它们指向相同的位置,因此这两个地址都将具有相同的地址。唯一的区别在于它们的类型。(arr+2)的类型为int(*)[2],而*(arr + 2)的类型int *