为什么"*(&arr + 4)"与"&arr [4]"不同?

Ede*_*nia 3 c pointers reference

int arr[] = { 0, 1, 2, 3, 4, 5 };
Run Code Online (Sandbox Code Playgroud)

我正在执行地址操作测试,以增加我对ref和deref的理解.这里有很多困惑.

我发现&*(arr+4)使用相同的地址,&arr[4]但我从未见过这样的任务&*

另外我认为*(&arr+4)使用相同的地址,&arr+4但它对我没有任何意义.

我找不到相关的信息,所以我会问这里,为什么*(&arr+4)使用相同的地址&arr+4,为什么*(&arr+4)不同&arr[4]呢?

Man*_*rse 12

arr 是一个数组:

arr: int[6]
[0|1|2|3|4|5]
Run Code Online (Sandbox Code Playgroud)

当在除sizeof arror 之外的表达式中使用时&arr,数组衰减到指向数组的第一个元素的指针:

(arr+0): int *
[*]
 |
 v
[0|1|2|3|4|5]
Run Code Online (Sandbox Code Playgroud)

当一个整数值被添加到指针时,你得到一个指向地址的指针,该地址(sizeof (T)) * n稍后是内存中的字节(其中T是指针指向的类型,并且n是添加到指针的整数值):

(arr+4): int *
        [*]
         |
         v
[0|1|2|3|4|5]
Run Code Online (Sandbox Code Playgroud)

取消引用指针后,您将获得指向的值:

*(arr+4): int
          4 /* specifically, the 4 in the fifth position in `arr` */
[0|1|2|3|[4]|5]
Run Code Online (Sandbox Code Playgroud)

当获取地址时int,您会得到一个指向该int的指针:

&*(arr+4): int *
        [*] /* notice, this is the same as (arr+4) */
         |
         v
[0|1|2|3|4|5]
Run Code Online (Sandbox Code Playgroud)

数组索引等效于指针添加,然后是解除引用:

arr[4] == *(arr+4) /* see above for definition of *(arr+4) */
Run Code Online (Sandbox Code Playgroud)

所以是的...... &*(arr+4)并且&arr[4]是等价的.

当获取数组的地址时,您将获得指向数组的指针:

&arr: int (*)[6]
[*] /* points to the array as a whole, not the first element of the array */
 |
 v
 [0|1|2|3|4|5]
Run Code Online (Sandbox Code Playgroud)

当您递增该指针时,相同的规则适用于上述:

                                    &arr + 4: int(*)[6]
               /*points into some memory that*/    [*]
               /* isn't part of the array... */     |
               /*  undefined behaviour       */     v
[0|1|2|3|4|5][x|x|x|x|x|x][x|x|x|x|x|x][x|x|x|x|x|x][x|x|x|x|x|x]
Run Code Online (Sandbox Code Playgroud)

由于这具有未定义的行为,因此您无法在不参考底层机器体系结构和编译器实现的情况下对其进行推理.

如果我们想象它已被很好地定义(如果arr是更大阵列的一部分那样)......我们可以继续.取消引用指向数组的指针会再次给出数组:

             /*the 5th array in this array of arrays*/ *(&arr+4): int[6]
   [0|1|2|3|4|5][x|x|x|x|x|x][x|x|x|x|x|x][x|x|x|x|x|x][[x|x|x|x|x|x]]
Run Code Online (Sandbox Code Playgroud)

您会发现*(&arr+4)(&arr+4)具有相同的地址,因为*(&arr+4)衰变为指向第一个元素的指针*(&arr+4),并且数组从其第一个元素开始,因此指向数组开头的指针和指向数组第一个元素的指针相同.

*(&arr+4)是不同的,&arr[4]因为它指的是一个完全不同的东西(见上文).