gcc学习笔记1

本文最后更新于 2024年2月5日 下午

此文章是 gcc 学习笔记,学习视频

1 多文件编译

目录结构如下:

main.c(主程序):

1
2
3
4
5
6
7
#include <stdio.h>
#include "hello.h"
int main()
{
hello("呵呵,ojbk");
return 0;
}

hello.h(函数的声明):

1
void hello(const char* str);

hello.c(函数的实现):

1
2
3
4
5
6
#include <stdio.h>
#include "hello.h"
void hello(const char* str)
{
printf("%s\n", str);
}

使用 gcc -Wall main.c hello.c -o hehe 命令进行多文件编译:

1.1 hello.h

在文件目录中有 hello.chello.hmain.c,但是在使用 gcc 编译时没有包含 hello.h

main.c 中的第二行 include 了 hello.hgcc -Wall main.c hello.c -o hehe 在执行这条命令时,gcc 读取到 main.c 源文件中的第二行,就会去找 hello.h 文件自动包含进来,所以不用包含头文件。

1.1.1 " "< >

main.c 中使用了 include <stdio.h>include "hello.h",这两种不同的包含符号有什么区别?

" " 表示编译器首先会到当前路径(被编译的源文件所在的路径)下搜索这个头文件,找不到再去系统头文件目录

< > 是直接去系统头文件目录下搜索头文件。

头文件目录(对于 Linux 系统)
/usr/include:系统上的标准头文件目录
/usr/local/include: 本地安装的软件包可能会将头文件放置在这个目录中

1.2 另外

在上述源文件中,hello.c 中的 include "hello.h" 可以删除,使用 gcc -Wall main.c hello.c -o hehe 编译时没有任何问题,为什么?

main.c 中包含了 hello.h 头文件时,这个头文件中的声明 void hello(const char* str); 告诉编译器有一个名为 hello 的函数,但是并没有提供该函数的具体实现。具体的实现在 hello.c 文件中。

编译器在编译 main.c 时,会查看 #include "hello.h",这会将 hello.h 文件的内容插入到 main.c 中。然后编译器会在 main.c 中找到函数声明 void hello(const char* str);。由于这只是一个声明,编译器并不知道函数的具体实现。

当你最后执行链接阶段(使用 gcc main.c hello.c -o hello)时,编译器会查找 hello 函数的实现。 这时,编译器看到了 main.c 中的调用 hello("呵呵,ojbk");,然后会在整个工程中搜索包含了 hello 函数实现的文件。由于你同时编译了 hello.c,所以编译器找到了 hello 函数的实现。 —— 正是因为同时将 main.chello.c 放在一起编译(gcc main.c hello.c -o hello)所以才不报错。

最终,链接器将 main.ohello.o 这两个目标文件合并,生成了可执行文件 hello


gcc学习笔记1
https://jwlee36963.github.io/posts/4e3171ca/
作者
jw
发布于
2024年2月5日
许可协议