一.翻译环境和运行环境
在ANSI C中存在两种不同的环境
翻译环境:将源代码转换成可执行的指令
比如:C语言代码被编译器转变成电脑能识别的二进制指令
运行环境:用于实际执行代码
二.翻译环境
翻译环境是由编译和链接两部分组成的
编译又分为预编译(预处理)、编译、汇编
C语言项目下可能有多个源文件
多个源文件单独通过编译器形成目标文件
windows下的目标文件后缀是.obj,linux下是.o
多个目标文件和链接库一起通过链接器链接形成可执行程序
库可能是支持基本函数运行的库,也可能是第三方的库
vs2022 IDE(编辑器、编译器、链接器、调试器)
gcc下的运行方式可能更复杂
1.编译
编译有词法分析,语法分析,语义分析
1.1语法分析
词法分析就是简单地将字符分割成关键字,标识符,括号,加号,乘号等
1.2语法分析
语法分析器将对各个符号进行语法分析,从而产生语法树
观察是否符合逻辑
arr[i] = (i+2)*(2+3)
比如:表达式 = 表达式
1.3语义分析
由语义分析器进行语义分析,即对表达式的静态分析
静态分析:通常包括声明和类型的匹配,类型的转换等。
这个阶段会报告出错误的语法信息。
比如:2 + 6 = 8
左边:int 类型 + int类型 = int类型
右边:int类型
赋值符号:左边 = 右边 -> int = int
1.4汇编
将汇编代码转换成二进制指令,即汇编是编译的最后一步,会生成目标文件,
1.5链接
链接是把一堆文件链接在一起才生成可执行程序
链接的过程包括:地址和空间分配,符号决议和重定位等
链接解决的是一个项目中多文件、多模块之间互相调用的问题
跟据图中信息,如果用add函数去找Add函数,这就是链接错误,符号表中有效的地址留下来,无效的地址删去
符号表中取合法的地址为合并后的地址是重定位
0x0000 对于0x0001来说是非法的
目标文件的分段都可以在《程序员的自我修养》中找到,
感兴趣的可以去了解
三.运行环境
1.程序必须加载入内存中。
2.程序的执行就开始了。接着就调用main函数
3.开始执行程序代码时。程序将使用一个运行时堆栈,每一个函数调用都会创建一个函数栈桢,创建堆栈会存储局部变量和返回地址。
程序也可以使用静态内存,存储在静态内存中的变量在整个程序执行过程中都会保留它们的值。
程序也可以使用动态内存,是由malloc,realloc,calloc开辟的动态内存,最后是由free函数释放掉动态开辟的内存的
创建栈桢,维护栈桢,销毁栈桢这是执行程序代码的栈桢维护的过程。
4.终止程序,正常终止main函数,也可能是意外终止(有可能是出BUG卡死,或突然没电了)