int a[10];
printf("%p ", &a);
将显示数组的地址a
。
所以,如果我执行重定向,*(&a)
为什么我没有得到存储在a[0]
. C 语言中规定我应该获得a
. 是的,这确实有道理,我得到了 的地址a
,因为*
和&
将相互取消导致简单a
的 ,即 的地址a
。
int a[10];
printf("%p ", (void *) &a); // address of the array
printf("%p ", (void *) a); // adress of the first element of the array
printf("%p ", (void *) *(&a));// same as above
这里, 的值a
与 相同&a[0]
。并且该值与对象为数组时的*&a
值相同。a
a
int
请注意,打印的地址将相同,因为它们都从相同的地址开始。
我添加了需要参数的void *
演员表。p
void *
管理这一点的 C 规则是 C 2011 6.3.2.1 3:“除非它是 sizeof 运算符、_Alignof 运算符或一元 & 运算符的操作数,或者是用于初始化数组的字符串文字,否则表达式类型为 ''array of type'' 的表达式转换为类型为 ''pointer to type'' 的表达式,该表达式指向数组对象的初始元素,而不是左值。”</p>
a
是一个 int 数组。当您传递a
给 printf 时,规则将其转换为指向 int 的指针,并打印该指针的值。
当您传递&a
给 printf 时:首先,a
是 的操作数&
,因此该规则不适用;a
不转换为指向 int 的指针;它仍然是一个 int 数组。二&
是评价。&a
产生数组的地址,并打印该地址。由于数组的地址与其第一个元素的地址相同,因此打印了地址。
请注意,表达式的类型&a
是“指向 int 数组的指针”。所以,当你有 时*&a
,你正在应用*
一个指向 int 数组的指针,结果是一个 int 数组。由于表达式是一个 int 数组,因此适用规则,并且这个 int 数组被转换为指向第一个元素的指针,并打印该指针的值。
事实:
a[0] == *(a)
a[9] == *(a+9)
计算结果的指针类型&a
是指向数组的指针(特别是指向 的指针int[10]
)。这是一种与指向数组第一个元素的指针不同的类型,即使它是相同的地址。
printf("%d ", *&a[0]);
将打印数组的第一个元素的值,因为 &a[0]
它具有 type int*
。