#include <stdio.h>
int main(void)
{
char s[32];
example_1:
scanf("%s", s);
printf("%s\n", s);
example_2:
scanf("%s", &s[0]);
printf("%s\n", s);
example_3:
scanf("%s", &s);
printf("%s\n", s);
}
为什么#3与其他2的工作方式相同?
#3有效吗?为什么呢?
答案 0 :(得分:9)
变体一取决于array decay,因此有效。
(在大多数情况下,数组衰减到指向其第一个元素的指针,例外是:地址 - (&s
),sizeof s
,_Alignas(s)
和_Alignof(s)
。)< / p>
变体2可以手动执行数组衰减并且更加冗长,因此更糟糕。
变体三严格Undefined Behavior,但它恰好适用于大多数实现
关键是&s
在默认促销后不属于char*
类型,但它指向正确的地址。
似乎工作是UB最危险的子集。
答案 1 :(得分:2)
虽然三者的类型不同:
s
是char[32]
(32个char
s的数组),在需要的地方透明地衰减到char*
&s[0]
是char*
(指向char
)&s
是char(*)[32]
(指向32 char
s的数组的指针)它们都解析为相同的值(字符数组的起始地址)。因此,当将其传递给期望printf
的{{1}}时,所有3的结果都是相同的(假设char*
的对象表示与char(*)[32]
的对象表示相同{1}},这是依赖于实现的,但通常是这种情况。)
只有前两个有效 - 第三个只是偶然起作用。