Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/extjs/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如果'&';不是放在';scanf&x27;陈述_C_Scanf_Stdio - Fatal编程技术网

如果'&';不是放在';scanf&x27;陈述

如果'&';不是放在';scanf&x27;陈述,c,scanf,stdio,C,Scanf,Stdio,我参加了一次面试,面试中有人问我这样一个问题: 你对以下几点有什么看法 int i; scanf ("%d", i); printf ("i: %d\n", i); 我回答说: 程序将成功编译 它将打印错误的数字,但它将一直运行到最后 不撞车 我的回答是错误的。我不知所措 之后他们解雇了我: 该程序在某些情况下会崩溃并导致内核转储 我不明白为什么程序会崩溃?谁能给我解释一下原因吗?感谢您的帮助。因为它会调用未定义的行为。当找到%d”说明符时,scanf()函数族需要指向整数的指针。您正在传

我参加了一次面试,面试中有人问我这样一个问题:

你对以下几点有什么看法

int i;
scanf ("%d", i);
printf ("i: %d\n", i);
我回答说:

  • 程序将成功编译
  • 它将打印错误的数字,但它将一直运行到最后 不撞车
我的回答是错误的。我不知所措

之后他们解雇了我:

该程序在某些情况下会崩溃并导致内核转储


我不明白为什么程序会崩溃?谁能给我解释一下原因吗?感谢您的帮助。

因为它会调用未定义的行为。当找到
%d”
说明符时,
scanf()
函数族需要指向整数的指针。您正在传递一个整数,该整数可以解释为某个整数的地址,但它不是。这在标准中没有定义的行为。它确实会编译(不过会发出一些警告),但它肯定会以一种意想不到的方式工作

在现有的代码中,还有另一个问题。
i
变量从未初始化,因此它将具有不确定的值,这也是未定义行为的另一个原因


请注意,该标准没有说明当您传递给定类型时会发生什么,而其他类型是预期的,这只是未定义的行为,无论您交换什么类型。但是这种特殊情况需要特别考虑,因为指针可以转换为整数,尽管只有当您转换回指针并且整数类型能够正确存储值时,才会定义该行为。这就是它编译的原因,但它肯定不能正常工作。

您将类型错误的数据(
int*
应为,但
int
已传递)传递到
scanf()
。这将导致未定义的行为

对于未定义的行为,任何事情都可能发生。程序可能会崩溃,也可能不会崩溃


在一个典型的环境中,我想当指向操作系统不允许写入的位置的某个“地址”被传递到
scanf()
时,程序会崩溃,写入该地址将使操作系统终止应用程序,并将其视为崩溃。

定义变量时,编译器为该变量分配内存

int i;  // The compiler will allocate sizeof(int) bytes for i
上面定义的
i
未初始化,且具有不确定的值

要将数据写入分配给
i
的内存位置,需要指定变量的地址。声明

scanf("%d", &i);
将由用户将
int
数据写入分配给
i
的内存位置

如果
&
未放在
i
之前,则
scanf
将尝试将输入数据写入内存位置
i
,而不是
&i
。由于
i
包含不确定值,因此它可能包含与内存地址值相等的值,或者可能包含超出内存地址范围的值


在任何一种情况下,程序的行为都可能不稳定,并将导致未定义的行为。在这种情况下,任何事情都可能发生。

其他答案尚未提及的一件事是,在某些平台上,
sizeof(int)!=sizeof(int*)
。如果参数以某种方式传递*,
scanf
可能会占用另一个变量或返回地址的一部分。更改返回地址很可能会导致安全漏洞

*我不是汇编语言专家,所以对此持保留态度

我不明白为什么程序会崩溃?谁能给我解释一下原因吗。谢谢你的帮助

也许更实用一点:

int i = 123;
scanf ("%d", &i);
使用第一个命令,为一个整数值分配内存,并在此内存块中写入123。对于本例,假设此内存块的地址为
0x0000ffff
。使用第二个命令,您读取输入,scanf将输入写入内存块
0x0000ffff
——因为您没有访问(取消引用)此变量
i
的值,而是访问它的地址


如果使用命令
scanf(“%d”,i)
而是将输入写入内存地址
123
(因为这是存储在此变量中的值)。显然,这可能会出现严重的错误并导致崩溃。

但在我的大学时代,当我学习C精神时,有一句话是这样的:
scanf(“%s”,name)^有效,因为
name
可能是一个字符数组,数组的名称等于该数组中第一个元素的地址。这是非常不同的。当然,
name
是一个数组,数组自动转换为指向其第一个元素的指针。而且,它会更安全
charname[100];scanf(“%99s”,名称)
。所以,基本上你的意思是说,
scanf
将尝试使用变量i在位置存储值。虽然你的评论不清楚,但我认为你确实理解了。是的,这就是它的工作原理。几乎可以保证你会崩溃,因为无论运行它的是什么系统,你都会遇到内存保护故障或类似的故障。当然,可能会发生其他事情,具体取决于程序的大小、分配的内存等,但我的钱花在系统/应用程序崩溃上。@sfdcfox我的钱花在编译器上,编译器注意到未定义的行为并将相应的代码块视为无法访问(=从代码中删除它并重定向指向它的任何代码路径)@JanDvorak我看到了编译器可以有效地“删除”前面提到的UB的想法,但是你知道有一个例子,我们可以看到它在起作用吗?这听起来难以置信——这就是为什么我很确定它是真的,因为这毕竟是C++。特别是在这里,你知道我吗