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]
&*(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]不同,因为它指的是完全不同的东西(见上文).