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

标签 c pointers reference

int arr[] = { 0, 1, 2, 3, 4, 5 };

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

我发现 &*(arr+4) 使用与 &arr[4] 相同的地址,但我从未遇到过 &*< 这样的赋值

我还认为 *(&arr+4) 使用与 &arr+4 相同的地址,但这对我来说没有任何意义。

我找不到相关信息,所以我就在这里问一下,为什么 *(&arr+4) 使用与 &arr+4 相同的地址以及为什么*(&arr+4)&arr[4] 不同吗?

最佳答案

arr 是一个数组:

arr: int[6]
[0|1|2|3|4|5]

当用在 sizeof arr&arr 以外的表达式中时,数组衰减为指向数组第一个元素的指针:

(arr+0): int *
[*]
 |
 v
[0|1|2|3|4|5]

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

(arr+4): int *
        [*]
         |
         v
[0|1|2|3|4|5]

当指针被取消引用时,您将获得指向的值:

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

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

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

数组索引等同于指针加法,然后取消引用:

arr[4] == *(arr+4) /* see above for definition of *(arr+4) */

所以是的... &*(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]

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

                                    &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]

由于这具有未定义的行为,因此如果不引用底层机器体系结构和编译器实现,就无法对其进行推理。

如果我们想象它被很好地定义(如果 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]]

你会发现 *(&arr+4)(&arr+4) 有相同的地址,因为 *(&arr+4) 衰减为指向 *(&arr+4) 的第一个元素的指针,而数组从其第一个元素开始,因此指向数组开头的指针和指向第一个元素的指针的数组将是相同的。

*(&arr+4)&arr[4] 不同,因为它指的是完全不同的事物(见上文)。

关于c - 为什么 "*(&arr+4)"与 "&arr[4]"不同?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23989206/

相关文章:

c - 如何从单个字符串中获取第二个标记?

c - C 中的结构声明和定义

c - 多线程信号量程序

php - 通过引用修改数组的问题

reference - 如何将引用的元组转换为元组的引用?

java - java - 如何测试对象引用在Java中使用了多少字节?

使用 TCP/IP 套接字检查有多少数据已传送到目的地

c - 递归函数除以一个数

c - 为什么我不能做 strcpy?

c - 从动态分配的指针数组打印错误