C 头文件如何知道函数原型的实现在哪里?

C 头文件如何知道函数原型的实现在哪里?,c,compilation,linker,header-files,C,Compilation,Linker,Header Files,我有以下文件: main.c #include <stdio.h> #include "my_math.h" int main() { int a = 10, b = 5; add(a, b); return 0; } #include "my_math.h" int add(int a, int b) { return a + b; } 我的数学.c #include <stdio.h> #include "my_math.h"

我有以下文件:

main.c

#include <stdio.h>
#include "my_math.h"

int main()
{
    int a = 10, b = 5;
    add(a, b);
    return 0;
}
#include "my_math.h"
int add(int a, int b)
{
    return a + b;
}
我的数学.c

#include <stdio.h>
#include "my_math.h"

int main()
{
    int a = 10, b = 5;
    add(a, b);
    return 0;
}
#include "my_math.h"
int add(int a, int b)
{
    return a + b;
}
我知道使用
#include“my_math.h”
会将my_math.h文件的内容复制到调用该文件的文件中。但是,main.c文件中的add()函数的实现在哪里? 起初我认为my_math.hmy_math.c应该匹配名称,但不是扩展名,但我已经将名称从my_math.c更改为my_matho.c,一切都像以前一样正常工作,那么c怎么知道函数的实现在哪里呢

我正在使用以下命令进行编译:

gcc -g -O0 -Wall main.c my_math.c -o main
还有一个问题,它是否与上一个命令相同:

gcc -g -O0 -Wall my_math.c main.c -o main

因此,这意味着我指示要编译的文件的顺序无关紧要。

有两个不同的阶段,编译和链接

  • 在编译过程中,编译器只需要知道函数的原型
  • 在链接过程中,对象文件实际上链接在一起
因此,在编译过程中,where部分不是必需的。但是,在链接时,该函数应该出现在链接在一起的一个对象文件中


更详细地说,这就是为什么我们看到,即使缺少头文件(函数的前向声明),但对于所有必需的对象文件,编译和链接也可以发生(显然带有警告)(链接器可以实际找到并链接所需的函数实现),但即使使用正确的头文件,如果您没有提供包含实际定义的所需对象文件,链接器将对您抛出错误发出尖叫。

编译器不知道。链接器是这样做的

每个源文件都编译为一个目标文件:

c变成main.o和my_math.c变成my_math.o-例如

编译
main.c
时,
my_math.h
中的函数原型告诉编译器将有一个函数
intadd(inta,intb)它可以调用它,但它没有关于此函数的额外知识


当链接器将main.o和my_math.o链接到可执行文件中时,它会执行必要的重新定位。

哦,这是一个非常好且清晰的解释。我认为在编译时,where很重要。谢谢。@SouravGhosh你所说的函数前向声明是什么意思?@lmiguelvargasf。基本上就是你在my_math.h中所做的