解密C语言编译背后的过程
我们大部分程序员可能都是从C语言学起的,写过几万行、几十万行、甚至上百万行的代码,但是大家是否都清楚C语言编译的完整过程呢,如果不清楚的话,我今天就带着大家一起来做个解密吧。
C语言相对于汇编语言是一种高级语言,要想在系统上运行,需要通过编译器把它转换成机器能够读懂的可执行的代码。
以Linux系统上的gcc为例,通常我们编译一个源文件都是用下面的命令:
$gcc hello.c –o hello
编译成功后,目录里会生成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) 连接
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,或者用其他编译器,原理都是一样的,感兴趣的同学可以去学习一下编译原理,会对编译有更深入的理解。
解密C语言编译背后的过程的更多相关文章
- C语言编译和链接过程
1.程序的编译 一般而言,大多数编译系统都提供编译驱动程序(complier driver),根据用户需求调用语言预处理器,编译器,汇编器和链接器.例如有如下历程://main.c void swa ...
- C语言编译过程简介
刚开始接触编程的时候,只知道照书敲敲代码,一直都不知道为什么在windows平台下代码经过鼠标那样点击几下,程序的结果就会在那个黑色的屏幕上.现在找了个机会将C语言的编译原理做一下小小的总结,这样也能 ...
- C语言编译过程(转)
内容摘要 : C语言编译的整个过程是非常复杂的,里面涉及到的编译器知识.硬件知识.工具链知识都是非常多的,深入了解整个编译过程对工程师理解应用程序的编写是有很大帮助的,希望大家可以多了解一些,在遇到问 ...
- C语言编译过程及数据类型
写在前面 C语言可以称得上是高级语言中的低级语言,接下来一段时间,我会写一下文章关于c语言,把它的神秘面纱一 一揭开.下面主要是c语言的C语言编译过程及数据类型 源文件编译过程 为了使计算机能执行高级 ...
- C语言编译过程以及gcc编译参数
1.1 C语言编译过程,gcc参数简介 1.1.1 C语言编译过程 一.gcc - o a a.c -o:指定文件输出名字 二.C语言编译的过程: 1.1.1 ...
- C语言基础(21)-C语言编译过程及GCC参数简介
任何C语言的编译过程可分为以下三部分: 一.预编译 在C语言中,以#开头的语句又叫预编译指令.预编译主要做以下两件事情: 1.将#include包含的头文件做简单的文本替换: 2.将代码中的注释删除. ...
- 转 C语言编译过程简介
C语言编译过程简介 C语言编译过程简介 刚开始接触编程的时候,只知道照书敲敲代码,一直都不知道为什么在windows平台下代码经过鼠标那样点击几下,程序的结果就会在那个黑色的屏幕上.现在找了个机会将C ...
- GCC 使用-C语言编译过程
任何一种高级语言,要想在机器上执行,必须翻译为机器能读懂的机器语言.编译器就相当于翻译官,将高级语言翻译为机器语言. GCC 最初只用了编译 C 语言程序,全称是 GNU C Compiler.后来扩 ...
- Go 语言编译过程
走进Golang之编译器原理_大愚Talk-CSDN博客 https://blog.csdn.net/hel12he/article/details/103061921 go编译器 - 知乎 http ...
随机推荐
- F - Dragon Balls
Five hundred years later, the number of dragon balls will increase unexpectedly, so it's too difficu ...
- windows批处理protoc生成C++代码
1 首先需要生成protoc的可执行文件,具体可以参考 https://www.cnblogs.com/cnxkey/articles/10152646.html 2 将单个protoc文件生成.h ...
- 基于canvas的画板
最近重新在看Html5&CSS3的知识,看到canvas的时候,想到了以前在学校学计算机图形学时做过的画图实验,于是想,可以基于html5和css3来做一款画板,经过1天的努力,完成了画板的一 ...
- javascript实例教程使用canvas技术模仿echarts柱状图
canvas 画布是HTML5中新增的标签,可以通过js操作 canvas 绘图 API在网页中绘制图像. 百度开发了一个开源的可视化图表库ECharts,功能非常强大,可以实现折线图.柱状图.散点图 ...
- api接口安全
API接口安全 在做app开发中,如何保证api的接口安全,不被其他app去调用? 接口安全的措施很多,今天记录一个常用的措施 签名: 前台想要调用接口,需要使用几个参数生成签名: 时间戳:当前时间 ...
- Java 多线程 -- volatile 山寨版的synchronized
在 多线程中,每个线程会把数据从主内存中拷贝到自己的工作内存中,当线程完成计算后,再把工作内存的数据更新到主内存中,或者当主内存主数据有更新是,线程会去主内存取最新数据.但是,当线程特别忙时,就不会去 ...
- discuz 自带的地区四级联动调用方法
首先,DZ提供了专门处理地区信息的函数,在source/function/function_profile.php(第14行)文件中:function profile_setting(){}那么,我们 ...
- QMessage自动定时关闭
QMessageBox *box = new QMessageBox(QMessageBox::Information,tr("test"),tr("testtest&q ...
- linux uniq 命令实用手册
Linux uniq 命令用于处理文本内容中的重复行. 这里我们只介绍其常用参数,其完整用法可参见man uniq. 例如,我们有如下文件内容: >>> cat log.txt __ ...
- 异常:NoSuchFieldError: BEST_MATCHING_HANDLER_ATTRIBUTE
出现的原因 pom 依赖之间不匹配导致 当前的 pom 调整后访问资源成功后面的 pom