我有以下程序
main()
{
char a,b;
printf("will i get the job:");
scanf("%c",&a);
printf("%c",a);
printf("We did it");
}
我将文件保存为Hope.c
。当我尝试使用gcc编译器编译上面的代码时,我将收到以下错误:
Hope.c:In function 'main':
Hope.c:4:2:warning:incompatible implicit declaration of built-in function 'printf' [enabled by default]
Hope.c:5:2:warning:incompatible implicit declaration of built-in function scanf[enabled by default]
当我使用printf()
或scanf()
时,即使在简单的“Hello world”程序中,编译器也会出现此错误。
我的代码有问题,或者编译器有问题吗?
答案 0 :(得分:6)
您在顶部缺少#include <stdio.h>
。请注意,这些都是警告,而不是错误。您的程序仍应按原样编译。
另外,为了更好地衡量,你应该将返回类型和参数写出来给main()并在结尾处返回一个值。
#include <stdio.h>
int main(void)
{
char a,b;
printf("will i get the job:");
scanf("%c",&a);
printf("%c",a);
printf("We did it");
return 0;
}
答案 1 :(得分:4)
当您调用您不熟悉的功能时,请查看手册页并包含那里提到的标题。在你的情况下它是#include <stdio.h>
。
这非常重要,例如虽然printf( "%s", func( ) )
返回了一个有效的以空字符结尾的字符串,但我没有遇到导致细分错误的func()
,但是没有原型将func()
的返回类型声明为char *
(做一个有点研究,我们发现只有64位指针的最后四个字节已经传递给printf()
)
答案 2 :(得分:2)
是的,代码有问题。您正在使用printf
和scanf
函数而不声明它们。
通常要做的是使用编译器附带的声明(因为它们已知是正确的)
#include <stdio.h>
答案 3 :(得分:2)
C.89 / C.90允许隐含的功能声明。您的警告消息通知您尚未提供scanf
和printf
的明确声明。如前所述,您可以通过将#include <stdio.h>
添加到程序的开头来更正此问题。如果不这样做,程序的行为就不明确了。
因为scanf()
和printf()
具有隐式声明,所以它们的原型被视为:
extern int scanf ();
extern int printf ();
这些声明声明scanf()
和printf()
采用未知数量的参数并返回int
。但是,这种声明仍假定这些函数将采用固定数量的参数。这与他们的真实原型不兼容,在这些原型中他们采用了可变数量的参数:
extern int scanf (const char *, ...);
extern int printf (const char *, ...);
你的C编译器显然知道这些函数的真正原型,因为它将这些函数视为“内置函数”,这意味着它可以在编译调用这些函数的源代码时生成特殊的大小写代码。由于隐式声明与其原型的内置知识不匹配,因此会生成警告。
没有这种“内置知识”的编译器可能不会生成警告。然后它会生成代码来调用scanf()
和printf()
,就像它们采用固定数量的参数一样。然后,错误可能在运行时发生,因为采用可变数量参数的函数的调用约定可能与采用固定数量参数的函数的调用约定不同。
这一切都在C.89§3.3.2.2中描述。
如果括号中的括号参数列表之前的表达式 函数调用仅包含标识符,如果不包含 声明对于此标识符是可见的,标识符是 在包含的最里面的块中隐式声明 函数调用,声明
extern int identifier();
出现了。
...
如果表示被调用函数的表达式具有该类型 不包括原型,执行整体促销 每个参数和具有float类型的参数都被提升为 双。 ...如果定义了函数 包含原型的类型,以及后面的参数类型 促销与参数的类型不兼容,或者如果 原型以省略号(“, ...
”)结束,行为是 未定义。
请注意,C.99删除了隐式函数声明的容差。