From e1f2f063d9477251e3068d324e71e5fd366d86c8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=AE=B8=E5=A4=A7=E4=BB=99?= <1900919313@qq.com> Date: Wed, 9 Oct 2024 00:53:51 +0000 Subject: [PATCH] =?UTF-8?q?2024=E5=B9=B410=E6=9C=889=E6=97=A5=2008:53?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/notes/02_c-leap/06_xdx/index.md | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/docs/notes/02_c-leap/06_xdx/index.md b/docs/notes/02_c-leap/06_xdx/index.md index 7b5532d..5c82eaf 100644 --- a/docs/notes/02_c-leap/06_xdx/index.md +++ b/docs/notes/02_c-leap/06_xdx/index.md @@ -12,7 +12,26 @@ > > 源程序需要以 `.c` 作为扩展名。 +* 过程 ② :编译,即:将 C 语言源程序转换为`目标程序(或目标文件)`。如果程序没有错误,没有任何提示,就会生成一个扩展名为 `.obj`或 `.o` 的二进制文件。C 语言中的每条可执行语句经过编译之后,最终都会转换为二进制的机器指令。 +> [!NOTE] +> +> - ① 其实,`编译阶段`包含了`预处理`、`编译`和`汇编`。 +> - ② `预处理`是编译过程的第一个阶段。在这个阶段,预处理器处理源代码中的指令(例如:`#include`、`#define`等),主要任务包括: +> - 头文件包含:将头文件的内容插入到源文件中。例如:`#include `会被替换为`stdio.h`文件的内容。 +> - 宏展开:替换宏定义。例如:`#define PI 3.14`会将代码中的`PI`替换为`3.14`。 +> - 条件编译:根据条件指令(如:`#ifdef`、`#ifndef`)有选择地编译代码。 +> - 删除代码中的注释,但是不会进行语法检查。 +> - 预处理完成后,生成一个扩展名为`.i`的中间文件。 +> - ③ `编译`是将预处理后的源代码转换为汇编代码的过程。在这个阶段,编译器会检查代码的语法和语义,将其转换为目标机器的汇编语言,生成一个扩展名为`.s`的汇编文件。 +> - ④ `汇编`是将汇编代码转换为机器代码(也称为目标代码或目标文件)的过程。在这个阶段,汇编器将汇编指令转换为二进制机器指令,生成一个扩展名为`.o`或 `.obj`的目标文件。 + +* 过程 ③ :链接(连接),即:将编译形成的目标文件 `*.obj` 或 `*.o`和库函数以及其他目录文件`链接`,形成一个统一的二进制文件 `*.exe`。 + +> [!NOTE] +> +> - 为什么需要链接库文件? +> - 因为我们的 C 程序会使用 C 程序库中的内容,如:`` 中的 `printf()` 函数,这些函数不是程序员自己写的,而是 C 程序库中提供的,因此需要链接。其实,在链接过程中,还会加入启动代码,这个启动代码(和系统相关,Linux 下主要有 crt0.c、crti.c 等,它们设置堆栈后,再调用 main() 函数)负责初始化程序运行时的环境。