当我们通常输入字符串时,我们会这样做:
#include <stdio.h>
int main()
{
char str[256];
scanf("%s",str);
//Other Operation
}
但是,今天,在编程课上,我的一个朋友scanf
这样写:
scanf("%s",&str);
它通过了编译,并且可以工作。
问题是,我想知道这在 C 语言中是否“合法”,或者只是未定义的行为?
这是未定义的行为(因为scanf()
期望的类型是char *
,但是您传入了 a char (*)[256]
),但它通常“有效”(似乎正在工作),因为数组的地址通常与(关于指针的数值)相同它的第一个元素的地址。
从官方文档:
如果此对象没有适当的类型,或者转换的结果无法在提供的空间中表示,则行为未定义。
(强调我的)
这是技术上未定义的行为。但是,这两种方法实际上都适用于 char 数组,因为str
传递给的引用scanf()
变成了指向第一个元素的指针,这将等于*指向数组本身的指针(的地址str
,或&str
),所以相同的值无论哪种方式都通过了。
我不确定到目前为止您是否只使用过字符串,但请记住,如果您查看不是数组的内容,则更容易判断您朋友的方法是正确的:
int myInt;
scanf("%d", &myInt);
scanf()
正在寻找一个指针,所以你想给它你的整数变量的地址。这是因为传递myInt
给它一个值(当前是垃圾),而&myInt
告诉它将读取的值放在哪里。
*Win16 除外。
str
和都&str
被定义为取数组第一个元素的内存地址的值。尽管 H2CO3 表明这是未定义的行为,但这在实践中总是有效的。