int main()
{
int a[3]={1,10,20};
printf("%u %u %u \n" ,&a,a,&a[0]);
return 0;
}
这会为所有三个打印相同的值。 我知道a和& a [0]是一样的但是& a也一样吗?
答案 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
,您引用了第一个元素的内存地址。