为什么我要在C中声明函数?

为什么我要在C中声明函数?,c,function,C,Function,我有两个源文件test1.c和test2.c 在test1.c中: #include <stdio.h> void main() { checks(); } #include <stdio.h> void checks(){ printf("This is a sample Text"); } 在这种情况下,我可以成功地构建和运行这个程序 那么我为什么要使用: void checks(); 要声明函数吗 现在看起来很好 我使用的是C99。

我有两个源文件
test1.c
test2.c

test1.c
中:

#include <stdio.h>

void main() {
    checks(); }
#include <stdio.h>

void checks(){
    printf("This is a sample Text");
    }
在这种情况下,我可以成功地构建和运行这个程序

那么我为什么要使用:

void checks();
要声明函数吗

现在看起来很好


我使用的是C99。

在您的例子中,
check()
函数有一个非常简单的原型,C编译器应用的默认原型是接受任何参数并返回一个
int
。这可能就是这里所做的(除了,因为您没有存储函数的结果,所以在没有注意到它的情况下对其进行了优化)

如果你想验证我的理论,试着写下这个(它应该一直工作到链接阶段):

最后,您的代码可以正常工作,因为链接器最终找到了可以插入
check()
函数的东西(但是,在某个点上,它仍然需要
int

事实上,函数原型的声明仅在两种情况下有用:

  • 函数的代码和函数的使用在同一个文件中

    当您在声明函数之前使用该函数(源代码)时,则需要告诉编译器在尝试静态键入您正在编写的函数时会发生什么(编译器从上到下读取源代码文件)

    例如:

    int bar (int a, int b, bool c);
    
    int foo (int a, bool b) {
        int result = bar (a, a, c);
        ...
    }
    
    int bar (int a, int b, bool c) {
        ...
     }
    
  • 函数的代码和函数的使用不在同一文件中

    然后,您通常通过头文件获得函数的定义,头文件收集编译器知道如何静态键入代码所需的所有信息。头文件(
    *.h
    )包含您正在使用的模块功能的所有原型。这些功能的实现将在连接时进行


  • 请注意,我通常会尽量避免第一种情况,因为它确实不符合逻辑。当你阅读一段源代码时,你会像编译器一样从上到下,你希望在函数定义被使用之前找到它。。。因此,以一种不需要这些工件的方式构造代码更符合逻辑。依我的拙见……

    它可能包含了警告。。。为了让编译器满意,你应该声明函数。你是怎么编译的?你在问什么?您是否在问为什么需要在使用函数之前声明它们?因为C是在20世纪80年代定义的,在那里有一个单通道编译器对性能很重要。
    void main
    这不是标准的C。尝试使用返回
    long long
    的函数,让它返回
    LLONG_MAX
    ,测试结果并获得启发。我使用int result=check();但是,尽管有一些警告,它仍然有效:/@jamius19,正如我已经说过的:“尝试[…]返回
    long
    ”,或者任何其他类型大于
    int
    。啊,这意味着尽管你的代码声明你有一个
    void check()
    编译器决定采用
    check()的默认原型
    并放弃了
    void
    。不知何故,匹配找到的第一个类型是编译器的行为。这并不奇怪。现在我在test1.c文件中将其声明为
    longchecks()然后设置
    int results=checks()我没有得到任何错误:/@perrorI猜测您得到函数末尾
    rax
    寄存器的内容作为返回值。。。这个例子很好地说明了一个事实,即C的类型检查器并非完全完美无缺,可以接受不可靠的东西。
    int bar (int a, int b, bool c);
    
    int foo (int a, bool b) {
        int result = bar (a, a, c);
        ...
    }
    
    int bar (int a, int b, bool c) {
        ...
     }