非常简单的C程序赢得';在gcc编译器中编译
我有以下程序非常简单的C程序赢得';在gcc编译器中编译,c,gcc,compiler-construction,C,Gcc,Compiler Construction,我有以下程序 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 declar
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”程序中,编译器也会出现此错误
我的代码是否有问题,或者编译器是否有问题?当您调用不熟悉的函数时,请查看手册页,并包括其中提到的标题。它是
#在您的案例中包含
这一点非常重要,例如,我经历过printf(“%s”,func())
导致分段错误,尽管func()
返回了一个有效的以null结尾的字符串,但没有原型将func()
的返回类型声明为char*
(做了一点研究,我们发现只有64位指针的最后四个字节被传递到printf()
)当您调用不熟悉的函数时,请查看手册页,并包含其中提到的标题。在您的例子中是\include
这一点非常重要,例如,我经历过printf(“%s”,func())
导致分段错误,尽管func()
返回了一个有效的以null结尾的字符串,但没有原型将func()
的返回类型声明为char*
(做一点调查,我们发现只有64位指针的最后四个字节被传递到printf()
)是的,代码有问题。您使用的函数printf
和scanf
,没有声明它们
通常要做的事情是使用编译器附带的声明(因为已知它们是正确的)
#包括
是的,代码有问题。您正在使用函数printf
和scanf
,但没有声明它们
通常要做的事情是使用编译器附带的声明(因为已知它们是正确的)
#包括
> p>您丢失了<>代码>在顶部包括。注意,这些警告不是错误。您的程序仍然应该按原样编译。
此外,为了更好地度量,您应该将返回类型和参数写入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;
}
#包括
内部主(空)
{
字符a,b;
printf(“我会得到这份工作吗:”);
scanf(“%c”和“&a”);
printf(“%c”,a);
printf(“我们做到了”);
返回0;
}
> p>您丢失了<>代码>在顶部包括。注意,这些警告不是错误。您的程序仍然应该按原样编译。
此外,为了更好地度量,您应该将返回类型和参数写入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;
}
#包括
内部主(空)
{
字符a,b;
printf(“我会得到这份工作吗:”);
scanf(“%c”和“&a”);
printf(“%c”,a);
printf(“我们做到了”);
返回0;
}
C.89/C.90允许隐式声明函数。您的警告消息通知您没有为scanf
和printf
提供显式声明。如前所述,您可以通过在程序开头添加\include
来纠正此问题。如果不这样做,您的行为r程序未定义
由于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取消了隐式函数声明的限制。C.89/C.90允许隐式函数声明。您的警告消息通知您