程序的编译和链接

本文详细解释了C语言源代码从编译到在屏幕上输出的过程,涉及编译环境(编译器、预处理、词法分析等)、链接过程以及执行环境(操作系统支持、运行时栈帧管理)

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

        前言:C语言的源代码到我们在屏幕上输出结果要经过两大环境,一个是翻译环境,一个是执行环境。其中翻译环境是由编译器控制, 执行环境是由操作系统控制。 本篇内容指向我们的C语言源代码是如何到在屏幕上输出结果,通过解析两大环境来进行说明。

        

        两大环境要做的大致内容如下

         我们自己写的C语言源代码是.c文件。翻译环境有两大工序, 一个是编译, 一个是链接。 然后就生成了我们的可执行程序, 也就是.exe文件,注意, 这些都是编译器帮我们做的。然后,我们打开.exe文件, 程序输出到屏幕上, 这个过程, 就用到了执行环境,注意, 它是操作系统帮我们做的。

        现在来讲翻译环境

翻译环境

        翻译环境主要分为两大部分, 编译和链接。 编译用到的是我们的编译器:vs之中是cl.exe; 链接用到的是我们的链接器:vs之中是link.exe。(vs是集成开发环境, 包括编辑器, 编译器, 连接器, 调试器)

        那么为什么会叫作翻译环境呢?那是因为翻译环境目的是将我们人能看懂的c语言代码, 逐步翻译为机器能够看懂的二进制指令。

        其中, 我们的.c文件经过编译器编译之中生成机器能够认识的二进制指令, 这个时候的文件是以.obj为后缀, 叫做目标文件。然后,目标文件之间再进行链接就生成了我们的.exe可执行程序。

        编译阶段

        编译阶段分为:预编译(预处理), 编译, 汇编。 

        预处理就是对我们的源代码.c文件进行预先的处理, 主要的作用就是:消除我们写的注释, 宏的替换,头文件展开等等操作。

        预处理之后我们的文件名就变成了.i文件

        .i文件进行编译, 编译后就是.s文件, 这个时候我们的.s文件之中就是一些汇编代码。

        .s文件经过汇编操作之后文件之中就是一些机器能够读懂的二进制指令, 也就是.obj文件。

        

       编译

        编译这个阶段分为词法分析, 语法分析和语义分析。 

        词法分析就是我们的代码在编译期间被扫描器进行扫描, 将我们的表达式分成一个一个的类型名, 比如 int a = 10;

这里的int 就被识别成类型名

a被识别为标识符,

=被识别为赋值,

10就是一个数字。

这就是词法分析。

        然后语法分析就是我们的编译器将我们的代码划分为一个语法树, 一个语法树。

比如这么一个式子:k = a + b + 6 + 7; 

这就是一棵语法树,以表达式为节点。  

        然后语义分析就是对语法分析生成的语法树进行静态的分析, 包括一些声明问题, 类型转换问题。 这一个过程就会进行编译的报错。 

        那么怎么进行分析呢?以上面的语法树为例。

 链接

        链接就是将一堆文件连接起来, 生成一个可执行程序。

        链接解决的是一个项目中,多模块, 多文件之间互相调用的细节。 

        如图:

 看这个文件中的Add

再看这个文件中的Add

第一个文件会有自己的目标文件, 并且这个文件会将自己文件内的函数的地址进行汇总, 假如Add的函数地址为0x1111 1111

然后main函数所在文件也对函数的地址进行汇总, 但是Add不是自己定义的, 它只能汇总成类似0x0000 0000这种无意义地址。 当然main函数也会被汇总。最后这些函数地址都会被汇总到一张符号表之中。 (有点类似c++虚函数表)

        然后就是链接了, 链接的时候会将所有文件的符号表进行合并。 然后这个时候发现main函数所在文件Add函数地址无意义。 那么他就会取那个有意义的Add的地址。 

运行环境

        当我们运行一个程序, 程序必须要载入内存之中,操作系统会帮助我们完成。如果没有操作系统, 那么程序载入必须我们手动载入, 比如单片机的烧录。

        程序载入成功后, 便开始调用main函数。 

        这个时候会生成一个运行时堆栈,也就是函数栈帧。 每一个函数的调用都会创建一个函数栈帧。每一个栈帧销毁时, 局部栈内存的空间编译器自动释放, 但是堆区的空间要我们自己释放。

        然后程序结束, 这个时候main函数结束, 可能是正常结束, 也可能是异常结束。 这取决与这个程序的设计。

        

评论 28
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值