首页 > 解决方案 > (&array)[1] 到底是什么?

问题描述

C中的这个Q ,为什么array、&array、&array[0]的地址是一样的?让我调查指针和数组:我确认它们非常相似但不相同。

&a[0]aor的详细形式&a。但是&vs的优先级[]呢?

当我像(&a)[1]这样以错误的方式放置括号时,会更改值,但不会(&a)[0]

#include <stdio.h>


int main(){
        int a[3] = {10,20,30};

        int *b;
        b = a;

        printf("%p a\n", a);
        printf("%p a+1\n", a+1);
        printf("%p a+2\n\n", a+2);

        printf("%p (&a)[0]\n",  (&a)[0]);
        printf("%p (&a)[1]\n",  (&a)[1]);
        printf("%p (&b)[0]\n",  (&b)[0]);
        printf("%p (&b)[1]\n\n",(&b)[1]);
        printf("%p cast\n\n", (void **)((&a) + 1)   );
        int *c = a;
        printf("%p\n",  c);
        printf("%p\n",  &c);
return 0;
}

输出:

0x7ffe18053c9c a
0x7ffe18053ca0 a+1
0x7ffe18053ca4 a+2

0x7ffe18053c9c (&a)[0]
0x7ffe18053ca8 (&a)[1]
0x7ffe18053c9c (&b)[0]
(nil)          (&b)[1]

0x7ffe18053ca8 cast

0x7ffe18053c9c c  (int *c = a)
0x7ffe18053c90 &c       

我发现(void **)((&a) + 1)得到相同的结果。似乎不能漏掉一块。突然间&a 确实创建了一个指针,匿名。

使用索引零,您可以获得基地址 (...c9c)a及其指针b。但是对于索引 1,会发生奇怪的事情,并且对于b.

有这方面的规则吗?我什至不知道我想不想听!&a除了在 and 之间a还有什么&a[0]


chux 的好 A。他的演员阵容更简单,但也一样吗?

C语言中&array和&array[0]的区别


从提到的链接中,我不仅简化了我的演员阵容,而且现在我想我知道它的作用以及为什么 0 的索引或偏移量是特殊的。

(void *)(&a + 0)是演员。但为什么还要投呢? &a + 0打印基地址。使用偏移量+ 1,地址会增加整个数组的大小(而不是我尝试过的指针) - “一个过去的结尾”。第二个维度。基数保持不变,但偏移量发生了变化。

对于分配:

int *c = a;
int (*d)[3] = &a;    // with some help from the left...
int *e = (int *)&a;  // ... or on the right side...
int *f = &a;         // or with a warning, but working

那么(&a)生成一个新类型,而不是一个指针?对同一地点的新参考。地址 = 指向 = 数组的指针。

标签: arrayscsyntax

解决方案


TL;博士:

  • &a[0]返回数组第一个元素的地址a。由于 C 中的数组几乎一直自动衰减(转换)为指向它的第一个元素的指针,因此您将通过查看aand观察到相同的行为&a[0]。但请注意,在某些情况下不会发生这种转换,最明显的一种是sizeof在数组上使用运算符。

  • (&a)[0]获取数组的地址,然后将结果视为数组并尝试访问它的第一个元素。这与仅取消引用结果指针相同,因此(&a)[0]与 相同*(&a),与 相同a。比见上文。

  • (&a)[1]几乎像以前一样,但它尝试访问从指向 array 的指针构造的假设数组的第二个a元素。由于这实际上不是一个数组,并且没有第二个元素,因此此代码格式错误,并触发Undefined Behavior


推荐阅读