C语言编译执行过程

一、C语言的编译执行过程

我们在C语言编辑的文件是以.c为文件拓展名的,称为源文件;C语言编译器的功能就是将源文件,经过编译、链接之后可以形成可执行文件

那么具体的步骤是什么呢?

C源程序头文件-->预编译处理(cpp)-->编译程序本身-->优化程序-->汇编程序-->链接程序-->可执行文件

二、编译执行过程详解

第一步:在编辑器中编辑源文件

第二步:编译预处理;

预处理的作用就是读取源文件中的字符流,对伪指令和特殊符号进行处理

预编译程序的功能是将源文件中的特殊内容进行替换,但是不会改变源文件的含义,预编译程序的输出文件将作为下一步操作的原始文件

伪指令(以#开头的指令)和特殊符号包括以下四种类型:

 1.宏定义指令:#define、#undef......#define Name *** 的功能是将源文件中的Name全部替换为***,而#undef的功能是取消某个宏的定义,使其不再生效

 2.条件定义指令:#ifdef、#ifndef、#endif等,这些伪指令的引入使得程序员可以通过定义不同的宏来决定编译工具对哪些代码进行处理,可以通过此方法过滤掉无用代码

 3.头文件包含指令:#include< >、#include" ",使用头文件的目的是使得某些定义可以被多个源程序引用,预编译程序将头文件中的定义加入到其输出文件中,以便编译程序能够对其进行处理;

 两者的区别为#include< >引用的是系统提供的头文件,而#include" "引用的为用户自定义头文件,其文件存放位置必须和源文件在同一路径

 4.特殊符号:预编译程序可以识别一些特殊符号,例如在源程序中出现的LINE标识将被解释为当前行号(十进制数),FILE则被解释为当前被编译的C源程序的名称

 

此外,在预处理阶段,编译器会删除注释内容,"//"和"/*"的内容,并且会添加代码行号和文件标识,便于在后续过程中输出报错信息时定位到错误位置

第三步:编译

经过预编译程序的处理,其输出文件将只包含变量。如数字、字符串、变量的定义,其工作就是将预编译处理程序进行语法检查和语句检查,确认语句符合规范之后,将其翻译为中间代码或者汇编代码

第四步:优化

优化是编译程序中的重要部分,它涉及到的问题不仅包括编译技术,还与机器的硬件环境有很大的关系

优化过程分为两种:一是对中间代码的优化,另一种是针对目标代码进行的生成进行的优化

第一种优化的主要方式是删除公共表达式以及循环优化,此方式不依赖计算机硬件平台,主要包括代码外提、强度削弱、变换循环控制条件、已知量的合并、复写传递以及无用赋值的删除

第二种优化则依赖硬件环境,最主要的问题是充分利用硬件的寄存器来保存有关变量的值,以减少内存访问次数,此外,根据机器硬件的指令特点将代码量减少以及增加代码执行效率也是很重要的问题

经过优化的代码必须经过汇编程序的汇编转化为机器指令才能够正常执行

第五步:汇编

汇编过程的主要功能是将汇编代码转化为机器指令,目标文件存放的就是和源文件相对应的机器指令

目标文件通常由段组成:数据段和代码段

代码段中包含的主要是程序的指令,一般文件权限是可读可执行但不可写

数据段中包含的主要是各种全局变量或静态变量的数据,一般文件权限为可读可写可执行

 

汇编程序生成的是可重定位文件,其中包含了其它目标文件链接来创建一个可执行文件或共享的目标文件所需的代码和数据

第六步:链接

 由汇编程序生成的目标文件并不能被直接执行,它可能还存在着许多的问题

 例如:某个源文件中的函数引用了另一个源文件中的内容,或者在程序中调用了函数库中的函数,解决这些问题必须进行链接这一过程

 链接过程的主要功能是将有关目标文件相互连接,也就是将在某文件中对其它文件的引用与另一个文件中此引用的定义链接,使得这些目标文件能够被操作系统装入执行的整体

 根据开发人员同库函数的链接方式的不同, 链接方式可分为:静态链接和动态链接

  • 静态链接:在这种链接方式下,函数的代码将从其所在地静态链接库中被拷贝到最终的可执行文件中,这样该程序在执行时,相关代码将被装载到该进程的虚拟地址空间中。静态链接库实际上是一个目标文件的集合,其中每个文件含有库中的一个或一组相关函数的代码
  • 动态链接:在这种链接方式下,函数的代码被放到动态链接库或共享对象的某个目标文件中。链接程序所做的就是在最终的可执行程序中记录下共享对象的名字以及相关登记信息。在可执行文件运行时,动态链接库中的所有内容都被映射到相应进程的虚地址空间中,可执行程序再根据相关登记信息找到相关执行代码

 

经过上述过程,C源程序就转化为了可执行程序,默认可执行程序的名字为a.out(Linux环境下)

三、编译过程中的文件类型

  •        在Windows平台上,C语言源代码文件一般扩展名为.c,目标文件扩展名一般为.obj,生成的可执行文件扩展名一般为.exe
  •   在Linux平台上,C语言源代码文件一般扩展名为.c,预处理操作后的文件名扩展名一般为.i,编译器生成的汇编代码一般扩展名为.s,生成的可执行文件一般扩展为.out,它是有汇编器生成的,所以默认gcc生成的程序名为a.out意思即为Assembler output
  • UNIX环境下主要有三种类型的目标文件:

    (1)可重定位文件  其中包含有适合于其它目标文件链接来创建一个可执行的或者共享的目标文件的代码和数据

    (2)共享的目标文件  这种文件存放了适合于在两种上下文里链接的代码和数据。第一种事链接程序可把它与其它可重定位文件及共享的目标文件一起处理来创建另一个目标文件;第二种是动态链接程序将它与另一个可执行文件及其它的共享目标文件结合到一起,创建一个进程映象

    (3)可执行文件 它包含了一个可以被操作系统创建一个进程来执行的文件

参考链接:http://lavasoft.blog.51cto.com/62575/187229

  • 2
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值