咱们大部分程序员可能都是从C语言学起的,写过几万行、几十万行、甚至上百万行的代码,可是你们是否都清楚C语言编译的完整过程呢,若是不清楚的话,我今天就带着你们一块儿来作个解密吧。程序员
C语言相对于汇编语言是一种高级语言,要想在系统上运行,须要经过编译器把它转换成机器可以读懂的可执行的代码。函数
以Linux系统上的gcc为例,一般咱们编译一个源文件都是用下面的命令:学习
$gcc hello.c –o hello
编译成功后,目录里会生成hello这个程序,直接运行它能够看到结果。操作系统
$./hello3d
Hello World!blog
但hello这个程序是怎么生成的呢,其实中间仍是有好几步的。用下面这个命令从新编译一下,你能够看到全部的中间文件。编译器
$gcc -save-temps hello.c –o helloio
$ls编译
hello hello.c hello.i hello.o hello.sclass
C编译器的编译过程主要分红四步:
(1) 预处理
(2) 编译
(3) 汇编
(4) 链接
1) 预处理 Pre-prosssing
预处理生成了hello.i 的中间文件,主要完成了下面几步:
去掉全部的注释
展开全部的宏定义(也就是作字符替换)
插入#include文件的内容
处理全部的条件编译
hello.i 文件内容以下(文件较大,只展现了最下面的一块):
能够发现源代码中全部的注释被删除了,而且插入了stdio.h头文件的内容。
2)编译 Compiling
编译将 hello.i 文件编译生成一个中间文件 hello.s,打开能够看到里边都是汇编语言,因此编译的做用就是把源代码转换成汇编语言。
3)汇编 Assembly
汇编器将 hello.s 汇编成 hello.o 文件。hello.o是二进制文件,里边都是机器能够执行的代码。
4)链接 Linking
链接顾名思义起到了一个链接做用,虽然 hello.o 已是二进制文件了,可是里边用到的好比 printf 函数须要调用别的库。链接器将咱们的二进制文件和其余库作了一个绑定。能够看到链接后生成的 hello 文件要比 hello.o 大的多。
到这里 C的完整编译流程就结束了,本文的示例用的是Linux操做系统,编译器用的是 gcc,但在其余操做系统,好比 Unix、Windows,或者用其余编译器,原理都是同样的,感兴趣的同窗能够去学习一下编译原理,会对编译有更深刻的理解。