前言:
我们在写c语言代码时,写在 .c(源文件) .h(头文件) 文件中,可以说代码是一种文本信息(文本文件),电脑对于c语言代码不能直接执行,都知道计算机能够执行的是二进制的指令,编译器就能够将代码变成可执行的二进制指令!!
目标文件: LINX系统是 .o
windos系统是 .obj
一、翻译环境:
将源代码转化为可执行的二进制指令(机器指令)
那么怎么做到呢??????????????????下面我们来探讨下:以win11为例
1、组成:
由编译和链接两个大过程组成;
2、编译:
可以细分为三个过程:预处理(预编译)、编译、汇编
1)、预处理(预编译):
这个阶段我们编写得.c .h等文件被处理为 .i 的后缀文件
如下:
处理的内容:主要是文件中#开始的预编译指令
(1)、#define删除,将所有的宏定义展开(即将运用宏定义的位置进行替换)
(2)、会去处理所有的条件编译指令,确定那些是进行使用的,如#if、#ifdef、#elif、#else、#endif等
(3)、#include预编译指令,将头文件的内容全部插入到预编译指令的位置,递归进行的(也就是我们的头文件里面也可以包含其他的头文件)
补充:为啥在引用自己的头文件时用的””而不是<>?
因为有一个规则,“”会直接从我们的目录文件(就是所在项目里的文件)里面找,没有再到库里找,而<>会编译器直接去库里面找到,不会查找目录文件;
(4)、删除所有的注释
(5)、添加行号和文件名标识,方便后续编译器生成调试信息等
(6)、保留所有#pragma的编译指令
2)、编译:
对于预处理后的文件,进行 词法分析、语法分析、语义分析以及优化,生成相应的汇编代码文件(.s)
词法分析:(词法分析器)
扫描仪,扫描代码,扫描里面的所有字符 将字符全部分割分割成下面记号
语法分析:(语法分析器)
一个“;(分号)”表示一个语法;相当于一句话。将里面的所有记号进行配对
内部就是像一棵树一样,在赋值符号两侧进行啊判断是否是正确的语法
语义分析:(语义分析器)
语法分析比较片面,只是配对,语义分析则是在这个层面上进行类型和声明的匹配,,若发生匹配不吻合 就会报错(错误的语法信息)
3)、汇编:(汇编器)
将汇编代码(.s)转变为二进制指令(目标文件 .obj),一个汇编语句对应一条二进制指令;机器则是根据汇编指令和机器指令对照表一一翻译,不会做任何优化
2、链接:
是一个比较复杂的过程,略微了解一下;我们在前面可以看见一个项目多个文件都是分开进行的编译并生成对应目标文件,那么要想一起使用,就需要链接,将他们链接起来。
链接可以看成连接,将一个项目中多个文件连接在一起生成可执行程序;
》》过程:
包括地址和空间分配,符号决议和重定位等
——>大致图如下:
3、综上,就是如下一张图:
二、运行(执行)环境 :
1. 程序必须载⼊内存中。在有操作系统的环境中:⼀般这个由操作系统完成。在独⽴的环境中,程序的载⼊必须由⼿⼯安排,也可能是通过可执⾏代码置⼊只读内存来完成。
2. 程序的执⾏便开始。接着便调⽤main函数。
3. 开始执⾏程序代码。这个时候程序将使⽤⼀个运⾏时堆栈(stack),存储函数的局部变量和返回地址。程序同时也可以使⽤静态(static)内存,存储于静态内存中的变量在程序的整个执⾏过程,⼀直保留他们的值。
4. 终⽌程序。正常终⽌main函数;也有可能是意外终⽌。
我们一般用的集成开发环境实现的,VS就是一个集成开发环境