我尝试了以下c程序&我希望得到编译时错误,但为什么编译器没有给出任何错误?
#include <stdio.h>
#include <conio.h>
int main()
{
int a,b;
printf("Enter a : ");
scanf("%d",&a);
printf("Enter b : ");
scanf("%d",b);
printf("a is %d and b is %d\n",a,b);
getch();
return 0;
}
我没在&
写scanf("%d",b)
。在编译时,编译器不会给出任何错误,但在执行期间b的值是2686792(垃圾值)。
答案 0 :(得分:2)
根据C11
标准,章节§6.3.2.3
整数可以转换为任何指针类型。除非事先指明,否则 结果是实现定义的,可能没有正确对齐,可能不指向 引用类型的实体,可能是陷阱表示。
因此,编译器将允许,但结果是实现定义的。
在这种特殊情况下,您将b
作为参数传递给scanf()
,未初始化,这将导致程序调用{{3}} ,一旦执行。
此外,printf()
/ scanf()
是可变参数函数,通常不会检查参数类型,除非通过编译器标志明确询问[参见-Wformat
]
答案 1 :(得分:1)
这不是编译时错误,而是运行时问题。
编译器希望你给出一个有效的地址来扫描值,在运行时只会知道地址是否有效。
如果您尝试将值扫描到无效地址,则会导致未定义的行为,并且可能会发生崩溃。
答案 2 :(得分:1)
它扫描正常,因为scanf
期望其参数中有一个内存位置。这就是我们使用&
给出相应变量的内存位置的原因。
在您的情况下scanf
只扫描输入的值并将其放入值为b
的内存位置(而不是扫描并将其放在b
的内存位置存储)。
答案 3 :(得分:0)
C中的&
运算符返回操作数的地址。如果您只给出没有&
运算符的b,它将按值传递,scanf
将无法设置该值。这会导致您已经注意到的意外行为。它无法在运行时之前验证地址,因此在运行时之前您不会注意到该问题。