数组静态声明中第一个元素的地址

时间:2011-06-24 19:13:55

标签: c

int main()
{
    int a[3]={1,10,20};
    printf("%u %u %u \n" ,&a,a,&a[0]);
    return 0;
}

这会为所有三个打印相同的值。 我知道a和& a [0]是一样的但是& a也一样吗?

5 个答案:

答案 0 :(得分:16)

为获得最大兼容性,您应始终使用%p并明确转换为void*以使用printf打印指针值。

当数组的名称在表达式上下文中使用而不是作为sizeof或一元&的操作数时,它会衰减到指向其第一个元素的指针。

这意味着a&a[0]具有相同的类型(int*)和值。 &a是数组本身的地址,因此类型为int (*)[3]。数组对象以其第一个元素开头,因此数组的第一个元素的地址与数组本身的地址具有相同的值,尽管表达式&a[0]&a具有不同的类型。

答案 1 :(得分:6)

我的C生锈了,但据我所知,& a是数组开头的地址,由于数组的开头是第一个元素,因此它将与& a [0]完全对应。

再次,生锈与C,所以我会推迟有更好的专业知识的人。

答案 2 :(得分:4)

& a恰好与a在这种情况下相同的事实是a是静态大小的事实的结果。如果你创建了一个指向数组的指针,那么它将是一个不同的数字,而另外两个给你相同的结果。

例如:

int main()
{
    int b[3]={1,10,20};
    int* a = b;
    printf("%u %u %u \n" ,&a,a,&a[0]);
    return 0;
}

示例输出是:

  

2849911432 2849911408 2849911408

答案 3 :(得分:3)

&a是“数组的地址”。这是数组所在的内存中的位置,但它有一个特殊类型“指向数组的指针”。

&a[0]是“数组第0个元素的地址”。由于在第0个元素之前的数组中没有任何内容,因此这是内存中的相同位置,但使用“指向”的类型。

a是“数组”。但是你无法真正按值传递数组到C或C ++中的函数(例如printf)。你只能假装这样做。 (在C ++中,你可以通过引用传递数组,但是C没有pass-by-reference。)但是真正发生的是数组“衰变”成指向第一个元素的指针,就像你写了{{1 }}

这是因为(我在这里主要推测)在C中,认为(a)能够修改传入数组的内容是有用和可取的; (b)在调用函数时不必将整个数组复制到堆栈中。所以C对你说谎并将指向原始数组的指针放到堆栈上。由于语法是相同的,你从来没有真正注意到差异 - 当你用你认为的数组写&a[0]但实际上是一个指针时,它会访问指向的内存,就像它是一个数组一样(是否或者它实际上是 - 没有办法告诉)。在C ++中,保留了行为以实现向后兼容。

答案 4 :(得分:1)

在C中,数组的名称指向该数组的第一个元素。

因此,通过声明&a,您引用了第一个元素的内存地址。