一个c语言代码变为c语言程序的全过程
#include <stdio.h>
int main(int argc, char const *argv[])
{
printf("hello world\n");
return 0;
}
这样一段代码通过编译器进行如下操作后来得到可执行文件
下面详细说明下每个步骤
预处理
根据#
开头的命令,将头文件命令行代码插入代码
可以用gcc -E hello.c -o hello.i 来只完成预处理
打开hello.i 可以发现代码前边多处500多行代码
这个可以在本机目录下找到stdio.h这个文件
这就是预处理的整个过程
编译
将hello.i编译成汇编语言,这个过程之后程序会更接近机器语言
这里解释下什么是机器语言,什么是高级语言
我们定义 00100 1 0的含义为1 + 0 即 00100 为加号 1 为被加数 0 为加数
这样写偏向于底层,在程序员看来是非常不直接的,不方便的。(这种二进制代码也被称为硬编码)
那我们再次规定,我们用add 1 0 来表示1 + 0,这样子容易理解多了,
(类似于早期这种比较简单语言称为汇编语言,这样的代码需要巨大的代码量来完成一些简单的逻辑)
人们使用汇编语言将常用的一些逻辑二次封装成为比较人性化的代码
再把 add 1 0 二次封装,为 1 + 0 这样,就很方便使用和理解
(这种代码就被称为高级语言,这种语言更符合人类的使用习惯)
上面这串代码从下往上的过程,就被称为代码的编译,处理它们的软件被称为编译器
使用 gcc -S hello.i -o hello.s可以将预处理后的文件编译为汇编语言的文件
汇编
将hello.s 打包成可重定位目标程序
hello.o
这一步已经将机器语言变成了二进制文件,用文本文件打开后会看到乱码
但仍然可以用二进制文本编辑器查看
链接
我们上边说过,早期人们将一些常用的逻辑打包,
一些常用逻辑包放在在标准库,使大家不需要每个函数都存放在代码里
就比如我们使用的printf 函数在标准库中的printf.o文件
在链接时,将hello.o 和printf.o两个文件打包成可执行文件
使用 gcc hello.o -o hello 就可以链接需要的文件得到可执行文件