解密C语言编译背后的历程

我们大部分程序员可能都是从C语言学起的,写过几万行、几十万行、甚至上百万行的代码,然则人人是否都清晰C语言编译的完整历程呢,若是不清晰的话,我今天就带着人人一起来做个解密吧。

 

C语言相对于汇编语言是一种高级语言,要想在系统上运行,需要通过编译器把它转换成机械能够读懂的可执行的代码。

 

以Linux系统上的gcc为例,通常我们编译一个源文件都是用下面的下令:

 $gcc hello.c –o hello 

解密C语言编译背后的历程

 

 

编译乐成后,目录里会天生hello这个程序,直接运行它可以看到效果。

$./hello

Hello World!

 

但hello这个程序是怎么天生的呢,实在中心照样有好几步的。用下面这个下令重新编译一下,你可以看到所有的中心文件。

$gcc -save-temps hello.c –o hello

$ls

hello hello.c hello.i hello.o hello.s

 

C编译器的编译历程主要分成四步:

(1) 预处置

(2) 编译

(3) 汇编

(4) 毗邻

解密C语言编译背后的历程

 

 

 

1) 预处置 Pre-prosssing

 

预处置天生了hello.i 的中心文件,主要完成了下面几步:

  • 去掉所有的注释

  • 睁开所有的宏界说(也就是做字符替换)

  • 插入#include文件的内容

  • 处置所有的条件编译

    某科学的PID算法学习笔记

     

hello.i 文件内容如下(文件较大,只展示了最下面的一块):

解密C语言编译背后的历程

 

 

可以发现源代码中所有的注释被删除了,而且插入了stdio.h头文件的内容。

 

 

2)编译 Compiling

 

编译将 hello.i 文件编译天生一个中心文件 hello.s,打开可以看到里边都是汇编语言,以是编译的作用就是把源代码转换成汇编语言。

解密C语言编译背后的历程

 

 

 

 

3)汇编 Assembly

 

汇编器将 hello.s 汇编成 hello.o 文件。hello.o是二进制文件,里边都是机械可以执行的代码。

解密C语言编译背后的历程

 

 

 

 

4)毗邻 Linking

 

毗邻顾名思义起到了一个毗邻作用,虽然 hello.o 已经是二进制文件了,然则里边用到的好比 printf 函数需要挪用其余库。毗邻器将我们的二进制文件和其他库做了一个绑定。可以看到毗邻后天生的 hello 文件要比 hello.o 大的多。

解密C语言编译背后的历程

 

 

 

 

到这里 C的完整编译流程就竣事了,本文的示例用的是Linux操作系统,编译器用的是 gcc,但在其他操作系统,好比 Unix、Windows,或者用其他编译器,原理都是一样的,感兴趣的同砚可以去学习一下编译原理,会对编译有更深入的明白。

原创文章,作者:admin,如若转载,请注明出处:https://www.2lxm.com/archives/8573.html