编写的C/C++代码,通过ide生成一个可执行文件,我们只需要点一下编译就可以实现,但实际上,我们点下编译之后,编译器经历了很多步骤,才最终生成了我们需要的软件。

在早期没有ide或者在Linux上我们自己配置的编译环境下,需要自己手动去执行预编译->编译->汇编->链接的步骤,最终生成我们的可执行文件。这有个好处是我们可以更了解c语言的编译原理。

预编译阶段

预编译阶段是将我们的一些预处理指令(头文件、宏定义等)以及注释进行处理。在Linux下的预编译会生成.i文件

gcc -E testCmp.c -o testCmp.i

此步生成的文件内容截取(因为内容太多了)

extern int ftrylockfile (FILE *__stream) __attribute__ ((__nothrow__ , __leaf__)) ;
extern void funlockfile (FILE *__stream) __attribute__ ((__nothrow__ , __leaf__));
# 868 "/usr/include/stdio.h" 3 4
# 2 "testCmp.c" 2
# 3 "testCmp.c"
int main()
{}

预处理指令指的就是我们在程序中在头部有#标志的,这是c语言的一个重要的知识,之所以叫他预处理指令,就是因为他在预编译阶段就被处理,此阶段会处理掉一部分内容,这部分内容不会进入到我们之后的步骤当中。

有时候我们在程序中会看到#if、#else,#elif、#endif,这些也是预处理指令,我们将编译他的阶段叫做条件编译,意思就是如果不符合#if或者#else或者#elif条件的程序部分,根本就不会编译进最终的可执行软件当中,这样可以大大减小我们的机器代码量。

当然,程序中少不了我们的头文件,预编译阶段会将头文件展开,将其中的内容,插入到源文件中。

还有一些比如宏定义,这个阶段会将宏定义内容替换到源码中

程序中不免有些注释的内容,我们在初学c语言的时候就听说,我们加多少注释都不会影响程序速度,因为预编译阶段会将注释内容删除,在之后的编译步骤中不会出现注释。

总结:

        1、头文件展开,内容插入到源文件

        2、宏定义内容替换源码中相应位置

        3、删除注释

        4、条件编译

编译阶段

编译阶段是将之前经过预编译阶段的代码,编译成汇编语言。实际上这一步在网络上有两种说法,一种说法是编译成机器代码,另一种是编译成汇编语言,实际上这两种说法也都没有错,只是一个细分和不细分的问题,我想的是既然要讲,就要细化的讲,我就将编译阶段分为两步来说。在Linux上此阶段会生成.s文件

gcc -S testCmp.i -o testCmp.s

这个阶段会进行一些语法上的词法分析、语法分析、语义分析、性能优化,经过这个阶段,我们的编译器会认识到我们在语法上的一些错误,从而发出警告或者严重的会直接抛出错误,使得编译终止。我们来看这一步生成的文件内容

  .file  "testCmp.c".text.globl  main.type  main, @function
main:
.LFB0:.cfi_startprocpushq  %rbp.cfi_def_cfa_offset 16.cfi_offset 6, -16movq  %rsp, %rbp.cfi_def_cfa_register 6movl  $0, %eaxpopq  %rbp.cfi_def_cfa 7, 8ret.cfi_endproc
.LFE0:.size  main, .-main.ident  "GCC: (Ubuntu 7.5.0-3ubuntu1~18.04) 7.5.0".section  .note.GNU-stack,"",@progbits

相信电气专业的朋友一定学过微机原理,里面两种处理器8086/88就是使用汇编来写,当时上大学这个头痛,因为汇编实在是不太符合写代码的思想。实际上汇编已经属于相对底层的语言了,现在我们使用最广泛的接近底层的代码就是c语言,本文不会对汇编进行深入剖析,有兴趣的朋友可以在网上了解,不过不太建议深入学,除非真的有需要。

总结:此步骤会检测我们的语法问题,也会进行一些优化处理,最终生成汇编语言文件

汇编阶段

汇编阶段会将我们上一步的汇编语言编译成目标文件。这个文件的内容为机器可以识别的二进制代码,非超底层程序员根本就不会看的懂这部分的代码,因为发明c语言这些可视化语言的目的就是为了防止与二进制代码直接打交道(头痛~)。

此步在windows下生成.obj,在Linux平台下生成.o

gcc -c testCmp.s -o testCmp.o

此步生成的文件是不能通过查看普通文件的方式被查看的,要使用专门的二进制查看软件查看,我这台电脑上没有查看器,所以也就不在这里列出了,朋友们只需要知道是一堆二进制代码就对了。

总结:生成机器可以识别的二进制代码

链接阶段

链接的目的是将一些依赖的库与我们的源文件合成最终生成可执行文件。我们将链接分为静态链接和动态链接,静态链接是依靠一个独立的链接器,将库文件与代码源文件合成生成一个独立的程序,这个有个弊端就是会导致我们的可执行程序很大,因为库文件本身就很大;另一个动态链接,动态链接库文件不会被编译到最终的软件中,而是在可执行软件中生成一个描述信息,我们根据信息去调用外部的动态链接库。

.lib和.a分别是windows和Linux下的静态链接库拓展名,.dll和.so分别是windows和Linux下的动态链接库拓展名。

Linux下执行生成最终目标文件

gcc testCmp.o -o testCmp

总结:此步分别使用动态链接库和静态链接库支持我们的软件,并生成最终软件

5分钟读懂c语言编译步骤相关推荐

  1. centos 删除文件夹_手机文件夹是英文,占空间还不敢乱删?花一分钟读懂手机语言...

    不少人肯定发现,自己的手机里面有一些莫名其妙的文件夹,占据内存空间.且占据很大,想删除,但全部是由英文标注,不知道从何删起. 今天小兰就来帮助大家决绝这么问题,一分钟教你读懂这些手机语言,快速清理手机 ...

  2. 5单个编译总会编译全部_5分钟读懂JavaScript预编译

    大家都知道JavaScript是解释型语言,既然是解释型语言,就是编译一行,执行一行,那又何来预编译一说呢?脚本执行js引擎都做了什么呢?今天我们就来看看吧. 1-JavaScript运行三部曲 语法 ...

  3. 计算机是如何读懂高级语言的——编译过程简述

    <计算机是如何读懂高级语言的--编译过程简述>源站链接,阅读体验更佳~ 前面的文章中我们简单介绍了高级语言的五大语法元素,以及这些语法元素是如何构成表达式,构成语句最终构成可执行的代码的. ...

  4. 语言编程思维陈萌_这本书告诉你,计算机为何能读懂人类语言,编程思维让你更聪明...

    在这个互联网时代,我们出门购物.拍照.打电话.浏览信息,只需要带上一部智能手机就可以了.如果在20年前,要实现这些功能,需要带一大堆东西.如今,我们口袋里的这台计算机,和50年前送宇航员上月球的那台计 ...

  5. 【光剑藏书轩2021】5分钟读懂《贫穷的本质》:“穷人通常缺少信息来源”

    5分钟读懂<贫穷的本质> <贫穷的本质:我们为什么摆脱不了贫穷>是2013年中信出版社出版的图书,作者是阿比吉特·班纳吉 (Abhijit V.Banerjee)与埃斯特·迪弗 ...

  6. 地铁供电系统原理图_策划|5分钟读懂地铁运行原理

    原标题:策划|5分钟读懂地铁运行原理 今日摘要 每日小编乘地铁上下班,昨天下午乘坐地铁时突然脑子中闪过一个问题那就是:地铁运行原理是什么?地铁隧道是怎么修建的?人踩在上面会不会有危险呢?今天小编带你一 ...

  7. [一篇读懂]C语言五讲:指针

    [一篇读懂]C语言五讲:指针 1. 指针的本质(间接访问原理) 1 指针的定义 2 取地址操作符与取值操作符,指针本质 2. 指针的==传递==使用场景 1 指针的传递 [例1.1]指针的传递使用场景 ...

  8. 如何读懂 C 语言复杂的声明

    如何读懂 C 语言复杂的声明 作者能力有限, 如果您在阅读过程中发现任何错误, 还请您务必联系本人,指出错误, 避免后来读者再学习错误的知识.谢谢! 参考<<C专家编程>> 废 ...

  9. Vue安装与IDE HBuilder安装(一分钟读懂)

    Vue安装与IDE安装(一分钟读懂) 官网下载IDE HBuilder 解压该文件后,打开 官网下载vue.js 创建demo文件夹,把vue.js放进这里面并且创建index.html文件 然后把这 ...

最新文章

  1. ElasticSearch安装使用 操作索引
  2. FileSystem close Exception
  3. BZOJ1030: [JSOI2007]文本生成器
  4. 开源OSS.Social微信项目解析
  5. 【Leetcode | 13】56. 合并区间
  6. 【qduoj】C语言课程设计_约瑟夫问题
  7. java按照商品价格排序_按照指定的类型排序
  8. Detected cartesian product for LEFT OUTER join
  9. Flutter学习笔记02:初探Flutter项目
  10. rust种的南瓜为什么老是消失_科技的力量!3种“奇葩”的发明,你都见过吗?...
  11. 数据结构排序系列详解之六 树形选择排序
  12. Arcgis执行Raster Project时报Error001143 : Background server threw an exception
  13. Android小游戏--2048
  14. PHP反三角函数,反三角函数求导公式
  15. C# 中Session的用法
  16. CentOS yum安装mcrypt详细图解教程
  17. thrift文件服务器,Thrift功能和使用
  18. 【C语言】 《弹跳的小球》游戏编写过程及思路,清屏函数、Sleep()函数的应用
  19. 互联网运营之道读书笔记
  20. unity 图片遮罩有锯齿_如何消除UGUI Mask遮罩的锯齿

热门文章

  1. 善良也好包容也好,为的更多是自己,而不完全是他人
  2. 打造メンアットワーク!魔兽学院men at work2《永远的羁绊》 中文终极版(刺杀事件、H补丁)
  3. 如何看日志报错 journalctl -xe
  4. Win10系统安装oracle及可能出现的问题
  5. 图论算法——幻象迷宫(洛谷 P1363)
  6. 试用期开除员工赔偿多少金额
  7. Redis三种启动方式
  8. 32 | 执行MySQL遇到kill不掉语句分析(此时你慌不慌)
  9. 教你5分钟实现百度首页搜索框,2分钟即时上线
  10. 计算机辅助教育的阶段,第一章计算机辅助教育概述.ppt