C头文件和编译/链接

我知道头文件具有各种函数,结构等的前向声明,这些函数,结构等在.c文件中用于“调用”#include,对吗?据我了解,“权力分立”的情况如下:

头文件:func.h

>包含函数的前向声明

int func(int i);

C源文件:func.c

>包含实际的函数定义

#include "func.h"

int func(int i) {
    return ++i ;
}

C源文件source.c(“实际”程序):

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

int main(void) {
    int res = func(3);
    printf("%i", res);
}

我的问题是:看到#include只是一个编译器指令,它在.include所在的文件中复制.h的内容,.c文件如何知道如何实际执行该函数?所有它得到的是int func(int i);,那么它如何实际执行该函数呢?它如何获得func的实际定义?标题是否包含某种“指针”,表示“那是我的定义,在那边!”?

它是如何工作的?

Uchia Itachi给出了答案.这是链接器.

使用GNU C编译器gcc,你可以编译一个单文件程序,如

gcc hello.c -o hello # generating the executable hello

但是,如您的示例中所述编译两个(或更多)文件程序,您必须执行以下操作:

gcc -c func.c # generates the object file func.o
gcc -c main.c # generates the object file main.o
gcc func.o main.o -o main # generates the executable main

每个目标文件都有外部符号(您可以将其视为公共成员).默认情况下,函数是外部函数,而(全局)变量默认是内部函数.您可以通过定义来更改此行为

static int func(int i) { # static linkage
    return ++i ;
}

要么

/* global variable accessible from other modules (object files) */
extern int global_variable = 10;

当遇到未在主模块中定义的函数调用时,链接器将搜索作为定义被调用函数的模块的输入提供的所有对象文件(和库).默认情况下,你可能有一些链接到你的程序的库,这就是你如何使用printf,它已经被编译成一个库.

如果您真的感兴趣,请尝试一些汇编编程.这些名称相当于汇编代码中的标签.

相关文章
相关标签/搜索