我最近在向同事解释原因时让自己感到尴尬
char a[100];
scanf("%s", &a); // notice a & in front of 'a'
非常糟糕,稍微好一点的方法是:
char a[100];
scanf("%s", a); // notice no & in front of 'a'
好的。对于每个准备告诉我为什么出于安全原因无论如何都不应该使用 scanf 的人:放轻松。这个问题其实是关于“&a”和“a”的意思。
问题是,在我解释了它为什么不起作用之后,我们尝试了它(使用 gcc)并且它起作用了 =))。我跑了一个快速
printf("%p %p", a, &a);
它会打印两次相同的地址。
谁能给我解释一下这是怎么回事?
最佳答案
嗯,&a
的情况应该很明显了。您完全按照预期获取数组的地址。
a
有点微妙,但答案是 a
是 数组。并且正如任何 C 程序员都知道的那样,数组往往会在最轻微的刺激下退化为指针,例如在将它作为函数参数传递时。
所以 scanf("%s", a)
需要一个指针,而不是数组,所以数组退化为指向数组第一个元素的指针。
当然 scanf("%s", &a)
也可以,因为这是数组的明确地址。
编辑: 哎呀,看起来我完全没有考虑 scanf 实际期望的参数类型。这两种情况都会产生一个指向相同地址但类型不同的指针。 (指向字符的指针,而不是指向字符数组的指针)。
我很乐意承认我对省略号 (...) 的语义了解不够,我一直像瘟疫一样避免这种情况,所以看起来转换为 scanf 最终使用的任何类型都可能是未定义的行为。阅读评论和 litb 的答案。你通常可以相信他能把这些东西做好。 ;)
关于c++ - char a[] 的语义,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/496226/