有人可以解释为什么以下三个片段中的输出相同。 以及数组的第0个元素究竟代表什么。
int main(void) {
char arr[10];
scanf("%s",&arr[0]);
printf("%s",arr);
return 0;
}
int main(void) {
char arr[10];
scanf("%s",&arr[0]);
printf("%s",&arr);
return 0;
}
int main(void) {
char arr[10];
scanf("%s",&arr[0]);
printf("%s",*&arr);
return 0;
}
答案 0 :(得分:2)
arr[0]
表示数组arr
的第一个元素。 &arr[0]
是数组的第一个元素的地址。在所有三个片段中,scanf
正在从标准输入读取字符串,并将存储在数组arr
中。
在第一个片段中
printf("%s",arr);
将在数组arr
中打印存储的字符串。 %s
期望char *
类型和&arr[0]
的参数属于该类型,因此arr
之后它将衰减为指向其第一个元素的参数。
在第二个代码段中,&arr
是数组arr
的地址,类型为char (*)[10]
。使用错误的说明符将调用未定义的行为。
在第三个代码段中,在*
上应用&arr
会将其取消引用回到数组arr
的第一个元素的地址,其类型为char *
,如上所述。
第一个和第三个片段是正确的,并且在输入字符串不应大于10
字符(包括'\0'
)的条件下,为同一输入提供相同的输出。第三个代码将调用未定义的行为,在这种情况下无法说出任何内容。
答案 1 :(得分:2)
&
(“地址”)和*
(“取消引用指针”)互相取消,因此*&foo
与foo
相同。
你的第二个片段错了。它将&arr
(一个指向10个字符数组的指针char (*)[10]
)传递给printf
%s
,它需要一个指向char(char *
)的指针。恰好在您的平台上,这两种类型具有相同的大小,使用相同的表示,并以相同的方式传递给printf
。这就是输出看起来正确的原因。
至于差异:arr
是一个字符数组。评估一个数组(即在&
或sizeof
的操作数以外的任何地方使用它)会产生一个指向其第一个元素的指针。
&arr
产生一个指向整个数组的指针。数组没有运行时结构(也就是说,在运行时数组是其元素),因此数组的地址也是其第一个元素的地址。只是第一个元素小于整个数组,两个地址有不同的类型。