在C语言中包含源文件

5
我了解标题和源文件的区别。我不明白的是编译器如何知道编译所有的源文件。例如:

example.h

#ifndef EXAMPLE_H
#define EXAMPLE_H

int example(int argument); // prototype

#endif

example.c

#include "example.h"

int example(int argument)
    {
    return argument + 1; // implementation
    }

main.c

#include "example.h"

main()
    {
    int whatever;
    whatever = example(whatever); // usage in program
    }

编译器如何在编译main.c时知道example()的实现,即使没有包含example.c文件?

这是一种IDE的功能吗,你需要将文件添加到项目中?是否有任何“手动”方式可以做到这一点,因为我更喜欢使用简单的文本编辑器而不是复杂的IDE?

5个回答

9

C或C ++中的编译实际上分为两个独立的阶段。

  • 编译
  • 链接

编译器不知道example()的实现。 它只知道有一个名为example()的东西将在某个时候被定义。 所以它只生成了有 example()占位符的代码

然后链接器会解析这些占位符。

要使用gcc编译您的代码,请执行以下操作

gcc -c example.c -o example.o
gcc -c main.c -o main.o
gcc example.o main.o -o myProgram

前两个gcc的调用是编译步骤。 第三个调用是链接器步骤。


我认为你在第二步中想表达的是 gcc -c main.c -o main.o。 - baskin

5

是的,您必须告诉编译器(通常是通过makefile来完成,如果您不使用IDE),哪些源文件需要编译成对象文件,编译器会逐个编译它们。然后,您将提供对象文件列表给链接器,以组合成可执行文件。如果链接器正在查找函数或类定义,并且找不到它,您将收到链接错误。


这就是makefile的作用,我一直好奇它们应该在哪里使用。谢谢。 - Core Xii

4

它不会自动做任何事情,你必须告诉它要做什么。
例如,在使用gcc时,首先需要编译文件:

gcc file1.c -c -ofile1.o
gcc file2.c -c -ofile2.o

然后编译器编译这些文件,假设你定义的符号(比如你的示例函数)在某个地方存在,并且稍后将被链接。然后将目标文件链接在一起:

gcc file1.o file2.o -oexecutable

此时,连接器查看这些假设并“澄清”它们,即检查它们是否存在。基本上就是这样工作的......

至于您的IDE问题,请搜索“makefiles”。


你的意思是使用 -c 而不是 -S,否则你就不应该将 .o 作为输出。 - Michael Krelin - hacker

1
编译器在编译main.c时不知道example()的实现 - 编译器只知道从头文件中包含的签名(如何调用它)。编译器生成.o对象文件,稍后由链接器链接以创建可执行二进制文件。构建过程可以由IDE控制,或者如果您喜欢Makefile。 Makefile具有独特的语法,需要一些学习才能理解,但会使构建过程更加清晰。如果您搜索Makefile,网络上有很多好的参考资料。

0
编译器本身不会做到这一点。但是您的构建工具可以。IDE 或 make 工具。手动创建 Makefile 是传统的方法。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接