8

当我们通常输入字符串时,我们会这样做:

#include <stdio.h>
int main()
{
    char str[256];
    scanf("%s",str);
    //Other Operation
}

但是,今天,在编程课上,我的一个朋友scanf这样写:

scanf("%s",&str);

它通过了编译,并且可以工作。

问题是,我想知道这在 C 语言中是否“合法”,或者只是未定义的行为?

4

3 回答 3

6

这是未定义的行为(因为scanf()期望的类型是char *,但是您传入了 a char (*)[256]),但它通常“有效”(似乎正在工作),因为数组的地址通常与(关于指针的数值)相同它的第一个元素的地址。

官方文档

如果此对象没有适当的类型,或者转换的结果无法在提供的空间中表示,则行为未定义。

(强调我的)

于 2013-08-13T16:45:00.740 回答
2

这是技术上未定义的行为。但是,这两种方法实际上都适用于 char 数组,因为str传递给的引用scanf()变成了指向第一个元素的指针,这将等于*指向数组本身的指针(的地址str,或&str),所以相同的值无论哪种方式都通过了。

我不确定到目前为止您是否只使用过字符串,但请记住,如果您查看不是数组的内容,则更容易判断您朋友的方法是正确的:

int myInt;
scanf("%d", &myInt);

scanf()正在寻找一个指针,所以你想给它你的整数变量的地址。这是因为传递myInt给它一个值(当前是垃圾),而&myInt告诉它将读取的值放在哪里。

*Win16 除外。

于 2013-08-13T16:51:57.350 回答
0

str和都&str被定义为取数组第一个元素的内存地址的值。尽管 H2CO3 表明这是未定义的行为,但这在实践中总是有效的。

于 2013-08-13T16:52:30.607 回答