【问题标题】:Why should I declare a function in C? [duplicate]为什么要在 C 中声明一个函数? [复制]
【发布时间】:2015-11-22 16:17:36
【问题描述】:

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

test1.c:

#include <stdio.h>

void main() {
    checks(); }

test2.c:

#include <stdio.h>

void checks(){
    printf("This is a sample Text");
    }

在这种情况下,我可以成功构建并运行这个程序。

那我为什么要使用:

void checks();

要声明函数?

现在看起来很好。

我正在使用 C99。

【问题讨论】:

  • 它可能在编译时带有警告......您应该声明该函数以使编译器满意
  • 你是怎么编译这个的?
  • 你在问什么?您是否在问为什么需要在使用函数之前声明它们?因为 C 是在 1980 年代定义的,当时拥有单遍编译器对性能很重要。
  • void main 这不是标准 C。
  • 尝试使用返回long long的函数,让它返回LLONG_MAX,测试结果并获得启发。

标签: c function


【解决方案1】:

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

如果你想检查我的理论,试着写这个(它应该可以工作,直到它到达链接阶段):

int result = check();

最后,您的代码可以正常工作,因为链接器最终找到了可以插入 check() 函数的东西(但是,它在某些时候仍然应该期待 int)。

其实函数原型的声明只在两种情况下有用:

  1. 函数的代码和函数的使用在同一个文件中。

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

    例如:

    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) {
        ...
     }
    
  2. 函数的使用代码不在同一个文件中。

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

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

【讨论】:

  • 我使用了 int result = check(); 但尽管有一些警告,它仍然有效:/
  • @jamius19 正如我已经说过的:“尝试 [...] 返回 long long”,或任何其他大于 int 的类型。
  • 啊,所以这意味着尽管你的代码声明你有一个void check(),但编译器决定采用check()的默认原型并丢弃void。不知何故,匹配找到的第一个类型是编译器的行为。并不令人惊讶。
  • 现在我在 test1.c 文件中将其声明为 long checks(); 然后设置 int results = checks(); 我没有收到任何错误:/ @perror
  • 我猜你在函数末尾得到了rax寄存器的内容作为返回值......这个例子很好地说明了C的类型检查器是并非完美无瑕,可以接受狡猾的东西。
猜你喜欢
  • 2019-11-05
  • 2014-10-15
  • 1970-01-01
  • 1970-01-01
  • 2020-03-03
  • 1970-01-01
  • 1970-01-01
  • 2016-08-21
  • 1970-01-01
相关资源
最近更新 更多