为什么编译器在将 int(不是 int *)作为 scanf() 的参数传递时不发出错误?
Why compiler is not issuing error while passing an int (not int *) as the argument of scanf()?
我尝试了下面的 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(垃圾值)。
根据 C11
标准,章节 §6.3.2.3
An integer may be converted to any pointer type. Except as previously specified, the
result is implementation-defined, might not be correctly aligned, might not point to an
entity of the referenced type, and might be a trap representation.
因此,编译器将允许这样做,但结果是实现定义的。
在这种特殊情况下,您将 b
作为参数传递给 scanf()
,它是 未初始化的 ,这将导致程序调用undefined behaviour,一次执行。
此外,printf()
/ scanf()
是可变参数函数,通常不检查参数 type ,除非通过编译器标志明确询问 [参见-Wformat
].
这不是编译时错误,而是运行时问题。
编译器希望您提供一个有效的地址来扫描值,只有在运行时它才会知道地址是否有效。
如果您尝试将值扫描到无效地址,则会导致未定义的行为并可能会发生崩溃。
它扫描得很好,因为 scanf
期望在其参数中有一个内存位置。这就是为什么我们使用 &
来给出相应变量的内存位置。
在你的情况下 scanf
只是扫描输入的值并将其放入值为 b
的内存位置(而不是扫描并将其放入 b
被存储)。
C中的&
运算符returns操作数的地址。如果只给出 b 而没有 &
运算符,它将按值传递并且 scanf
将无法设置值。正如您已经注意到的那样,这将导致意外行为。它无法在运行时之前验证地址,因此您直到运行时才会注意到这个问题。
我尝试了下面的 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(垃圾值)。
根据 C11
标准,章节 §6.3.2.3
An integer may be converted to any pointer type. Except as previously specified, the result is implementation-defined, might not be correctly aligned, might not point to an entity of the referenced type, and might be a trap representation.
因此,编译器将允许这样做,但结果是实现定义的。
在这种特殊情况下,您将 b
作为参数传递给 scanf()
,它是 未初始化的 ,这将导致程序调用undefined behaviour,一次执行。
此外,printf()
/ scanf()
是可变参数函数,通常不检查参数 type ,除非通过编译器标志明确询问 [参见-Wformat
].
这不是编译时错误,而是运行时问题。
编译器希望您提供一个有效的地址来扫描值,只有在运行时它才会知道地址是否有效。
如果您尝试将值扫描到无效地址,则会导致未定义的行为并可能会发生崩溃。
它扫描得很好,因为 scanf
期望在其参数中有一个内存位置。这就是为什么我们使用 &
来给出相应变量的内存位置。
在你的情况下 scanf
只是扫描输入的值并将其放入值为 b
的内存位置(而不是扫描并将其放入 b
被存储)。
C中的&
运算符returns操作数的地址。如果只给出 b 而没有 &
运算符,它将按值传递并且 scanf
将无法设置值。正如您已经注意到的那样,这将导致意外行为。它无法在运行时之前验证地址,因此您直到运行时才会注意到这个问题。