到目前为止,我们一直在研究那些大部分代码都写在单个文件里的简单程序。但复杂的 C 程序由多个文件组成,这些文件会被编译并链接成一个可执行文件。

在本章中,我们将了解一些常见的模式和实践,以便更好地组织大型项目。

17.1 Includes and Function Prototypes

一个非常常见的情况是,你的一些函数定义在一个文件里,而你想从另一个文件调用它们。

这实际上开箱即用,但会有警告……我们先试一试,然后再看看修复警告的正确方法。

在这些例子中,我们会把文件名写成源代码里的第一条注释。

要编译这些文件,你需要在命令行上指定所有的源文件:

gcc -o foo foo.c bar.c

在这个例子里,foo.cbar.c 被编译并链接到名为 foo 的可执行文件中。

接下来,我们来看一下源文件 bar.c

// File bar.c

int add(int x, int y)
{
    return x + y;
}

文件 foo.c,其中包含 main 函数:

// File foo.c

#include <stdio.h>

int main(void)
{
    printf("%d\\n", add(2, 3));  // 5!
}

你可以看到,我们从 main() 调用了 add() 函数——但 add() 定义在完全不同的源文件里!它在 bar.c 中,而调用发生在 foo.c

如果我们用下面的命令编译:

gcc -o foo foo.c bar.c

我们会得到这个错误:

error: implicit declaration of function 'add' is invalid in C99

(或者你可能会收到警告,但你不应该忽视它。C 语言中的警告绝不可忽略,必须全部处理!)

如果你还记得函数原型(prototypes)那部分内容,你会知道在现代 C 中隐式声明函数是被禁止的,没有正当理由在新代码里引入它们。我们应该修复这个问题。