💻1.背景知识
🍲1. 预处理(进行宏替换)
预处理阶段我们要分为1.头文件展开2.宏替换3.条件编译4.去掉注释
这一步会帮助我们生成.i文件
🍲2. 编译(生成汇编)
编译阶段我们要分为1.检查语法2.生成汇编代码
最后生成.s文件
🍲3. 汇编(生成机器可识别代码)
汇编阶段我们要将代码转化成二进制的机器码(CPU可识别)
生成.o文件
🍲4. 链接(生成可执行文件或库文件)
合并文件 链接一些没有确定的函数的地址等’
生成a.out文件
💻2.gcc如何完成
🚩格式 gcc [选项] 要编译的文件 [选项] [目标文件]
🚩预处理(进行宏替换)
预处理功能主要包括宏定义,文件包含,条件编译,去注释等
预处理指令是以#号开头的代码行
实例: gcc –E hello.c –o hello.i
选项“-E”,该选项的作用是让 gcc 在预处理结束后停止编译过程
选项“-o”是指目标文件,“.i”文件为已经过预处理的C原始程序
📍编译(生成汇编)
在这个阶段中,gcc 首先要检查代码的规范性、是否有语法错误等,以确定代码的实际要做的工作,在检查无误后,gcc 把代码翻译成汇编语言
用户可以使用“-S”选项来进行查看,该选项只进行编译而不进行汇编,生成汇编代码
实例: gcc –S hello.i –o hello.s
🔫汇编(生成机器可识别代码)
汇编阶段是把编译阶段生成的“.s”文件转成目标文件
读者在此可使用选项“-c”就可看到汇编代码已转化为“.o”的二进制目标代码了
实例: gcc –c hello.s –o hello.o
📞链接(生成可执行文件或库文件)
在成功编译之后,就进入了链接阶段
实例: gcc hello.o –o hello
这里问大家一个小问题 请问现有的语言还是先有的编译器呢?
答案是现有的语言
我们最早的是二进制 然后是汇编语言这种低级语言的诞生 然后诞生了C语言这种高级语言 最后在C语言的改造上诞生了C++面向对象的高级语言
首先我们虽然没有可识别汇编语言的汇编编译器 但是我现在有二进制 我就用二进制写了一个汇编编译器出来 编译器是一个软件 那么我们现在用汇编写一个编译器怎么形成一个软件呢?所以我们用二进制编译器编译就形成了一个第一个用汇编语言写的编译器就诞生了
由于编译器自身需要优化换代 我们就自己淘汰自己生成更好的自己 我们把这个过程称之为语言和编译器的自举过程
🎼那么C语言也是同一个道理 具体见上图
当我把1.0和2.0都屏蔽掉的时候就直接执行else语句
上述问题的就是我们程序在预处理阶段 编译汇编以及链接生成可执行程序期间的所有指令 现阶段先按照指令按部就班的写 等后期学习得更加深入我们在详细阐述
思考下面问题
感兴趣的同学可以把答案写在评论区 我看到了话会给出解释的哦
💻3.动态库和静态库
静态库是指编译链接时,把库文件的代码全部加入到可执行文件中,因此生成的文件比较大,但在运行时也就不再需要库文件了。其后缀名一般为“.a”
动态库与之相反,在编译链接时并没有把库文件的代码加入到可执行文件中,而是在程序执行时由运行时链接文件加载库,这样可以节省系统的开销。动态库一般后缀名为“.so”,如前面所述的 libc.so.6 就是动态库。gcc 在编译时默认使用动态库。完成了链接之后,gcc 就可以生成可执行文件,如下所示。 gcc hello.o –o hello
gcc默认生成的二进制程序,是动态链接的,这点可以通过 file 命令验证
这个动静态库有点难以理解 我们这里以孩子在学校上课周末写完作业去网吧打游戏的例子 看下图
解释:此时我们的网吧就是动态库 我们每个个体是一个个的内存 可执行程序 现在是周末 我按照计划写完了周末作业 现在要去网吧打游戏了 去到网吧就叫到老板说 老板给我开个十号机 然后打了一个小时之后就就回到学校了 不光是我一个人在网吧打游戏 我的室友他们都在网吧打游戏 都是打了一个小时就回寝室继续写作业了 但是有一天 网吧被人举报了 当地的派出所就立马过来警告网吧老板让老板停店整顿 然后有一次年级考试 我成功的考到了第一 回家让爸爸给我买一台电脑 我说我喜欢网吧的那台十号机 老爸就给我整了一台放在学校寝室里面了 然后另一个同学考了年纪第二 他也要让他的爸爸给他买一台电脑 她说他喜欢网吧里的六号机 他爸爸也给他买了一台六号机放在学校寝室 接着剩下的同学都如此 过了一段时间以后 网吧恢复营业了 发现最近的生意没有平时好了 老板这才想起电脑都已经卖出去了 此时网吧就成为了静态库 希望大家能够理解
静态库:允许拷贝
动态库:允许关联
💻4.gcc选项
-E 只激活预处理,这个不生成文件,你需要把它重定向到一个输出文件里面
-S 编译到汇编语言不进行汇编和链接
-c 编译到目标代码
-o 文件输出到 文件
-static 此选项对生成的文件采用静态链接
-g 生成调试信息。GNU 调试器可利用该信息。
-shared 此选项将尽量使用动态库,所以生成文件比较小,但是需要系统由动态库.
-O0
-O1
-O2
-O3 编译器的优化选项的4个级别,-O0表示没有优化,-O1为缺省值,-O3优化级别最高
-w 不生成任何警告信息。
-Wall 生成所有警告信息
💻5.gcc选项记忆
ESc,iso例子