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/