用scanf读取字符串

abe*_*eln 136 c scanf

我对某些事情有点困惑.我的印象是,读取C字符串的正确方法与之scanf()相符

(不要介意可能的缓冲区溢出,这只是一个简单的例子)

char string[256];
scanf( "%s" , string );
Run Code Online (Sandbox Code Playgroud)

但是,以下似乎也有效,

scanf( "%s" , &string );
Run Code Online (Sandbox Code Playgroud)

这只是我的编译器(gcc),纯粹的运气还是别的什么?

Gar*_*han 131

数组"衰减"为指向其第一个元素的指针,因此scanf("%s", string)相当于scanf("%s", &string[0]).另一方面,scanf("%s", &string)传递一个指针指向char[256],但它指向同一个地方.

然后scanf,当处理其参数列表的尾部时,将尝试拉出一个char *.当你传入string或者传入时,这是正确的事情&string[0],但是当你传入时,&string你依赖于语言标准不能保证的东西,即指针&string&string[0]- 指向不同类型和大小的对象的指针从同一个地方开始 - 以同样的方式表示.

我不相信我曾经遇到过一个不起作用的系统,而且在实践中你可能很安全.尽管如此,这是错误的,它可能会在某些平台上失败.(假设的例子:一个"调试"实现,包括每个指针的类型信息.我认为 Symbolics"Lisp Machines"上的C实现做了类似的事情.)

  • +1.验证数组衰减导致`&string`与`string`的工作方式相同(而不是导致随机内存损坏,因为其他答案错误地断言)也是微不足道的:`printf("%x \n%x \n", string,&string);` (5认同)
  • @abeln:正确.对于通过malloc()分配的字符串,`string`是一个指针,`&string`是该指针的地址,因此这两个不可互换.正如Gareth解释的那样,即使对于数组衰减的情况,`string`和`&string`在技术上也不是相同的类型(即使它们恰好可以在大多数架构中互换),如果你的话,gcc会给你的第二个例子发出警告打开`-Wall`. (4认同)