1

我的理解是,为了使用在头文件中声明并在匹配的源文件中定义的函数,必须在 main() 之前包含所述头文件。那么为什么下面的编译和运行使用得很好:

gcc -o 你好 hellomain.c 你好.c

hellomain.c

int main(int argc, char *argv[])
{
    helloPrint();

    return 0;
}

你好.h

#ifndef hello_h
#define hello_h

void helloPrint();

#endif

你好ç

#include <stdio.h>

void helloPrint()
{
    printf("Hello, World!");
}

这显然是一个非常简化的例子,但它说明了我的问题;为什么我不必在“hellomain.c”中包含“hello.h”?谢谢!

4

2 回答 2

4

当使用没有原型的函数时,编译器会对其返回类型和它采用的参数做出某些假设。在这种情况下,这些假设恰好是有效的,即使它假设函数返回一个int.


正如 Eric Postpischil 在评论中指出的那样,非常不鼓励省略原型,因为它可能会导致细微的错误。您应该始终确保您的函数调用具有可用的所需原型,最好包括它们相应的标头。

于 2013-01-21T20:30:50.337 回答
3

当您在 C 源文件中使用未声明的函数时,编译器会从调用派生参数并假定返回类型为 int。

根据 ISO 标准“编程语言 - C”

6.5.2.2 函数调用
6 如果表示被调用函数的表达式具有不包含原型的类型,
...
如果自变量的数量不等于参数的数量,则行为未定义。

这意味着,当你使用一个函数而不声明它并且你的参数数量和函数的实际参数数量不一致时,所有的赌注都没有了。

...
如果函数定义的类型不包含原型,并且提升后的参数类型与提升后的参数类型不兼容,则行为未定义,...

此外,当您使用一个函数而不声明它并且您的参数类型和函数的实际类型不匹配时,任何事情都可能发生。

因此,尽管它在某些情况下可能有效,但您应该声明您在程序中使用的函数。如果不这样做,编译器将无法帮助检测函数声明和函数调用之间的不匹配。

于 2013-01-21T20:32:15.627 回答