【c语言】(编译

您所在的位置:网站首页 c语言剖析 【c语言】(编译

【c语言】(编译

2024-02-02 12:17| 来源: 网络整理| 查看: 265

目录

​​​

前言

一、 程序的翻译环境和执行环境

二、翻译环境

2.1编译本身也分为三个阶段:

2.2预编译

2.3编译

2.4汇编

2.5链接

三、运行环境

总结

前言

    1.当我们刚开始学习c语言的时候。很多人都会被告知:一个程序是要经过编译--链接--执行这三个部分为,包括我记得大一时期末c语言的填空题也是如此。但是有没有人想过这看似简单的步骤其背后蕴含的复杂机制。比如:程序为什么要经过编译器进行编译后才可以运行?#include有什么用?编译出来的可执行文件里面是什么?这些问题都会在本篇文章中进行解答

2.本文章的程序都是centos7.6环境下运行的。

一、 程序的翻译环境和执行环境 在ANSI C的任何一种实现中,存在两个不同的环境。 第1种是翻译环境,在这个环境中源代码被转换为可执行的机器指令。 第2种是执行环境,它用于实际的代码执行。

 

二、翻译环境

比如说我们创建一个test.c,我们就写一个非常简单的c语言程序。

 

我们编写的test.c就是一个源文件,它通过编译器编译成目标文件,再通过连接器链接成可执行文件。编译是针对一个源文件的,有多少个源文件就需要编译多少次,就会生成多少个目标文件。

 

2.1编译本身也分为三个阶段:

还是拿上面写的test.c为例,在编译的过程中会先进行--预编译--编译--汇编,这三个阶段,每个阶段编译器都有不同的职责。

2.2预编译

在Linux的环境下如果我们想要查看,test.c预编译后会产生哪些变化,我们可以输入指令gcc -E test.c -o test.i,此时我们查看test.i这个文件

 

这时我们发现在test.i这个文件中

1.#include消失了,与之带来的时文件中多了八百多行代码

2.我们写的注释消失不见了

3.我们定义的#define MAX 20 被替换了 

由此我们可以得出结论在预处理阶段编译器为我们做了:

1.展开头文件

2.#define 定义符号的替换

3.删除注释

2.3编译

在编译阶段,编译器会进行,1.语法分析(检测是否有语法错误)2.词法分析 3.语义分析 4.符号汇总,最终转化为汇编代码。而这一块都知识涉及到编译原理相关的知识,这里不做展开详解,如有兴趣的同学,可以看看编译原理相关的书。

2.4汇编

在汇编阶段,编译器会将已经经编译好的test.c里面的汇编代码转化为二进制指令(机器指令)

在Linux我们可以通过输入指令gcc -c test.c 得到test.o文件进行查看

 此时我们可以看到很多我们看不懂的乱码,这些就是二进制指令。

2.5链接

       链接的主要功能是:1.合并段表 2.符号表的合并和符号表的重定位。如果你对这个功能的阐述不理解的话可以看下面的解释:

     C语言代码经过编译以后,并没有生成最终的可执行文件(.exe 文件),而是生成了一种叫做目标文件(Object File)的中间文件(或者说临时文件)。目标文件也是二进制形式的,它和可执行文件的格式是一样的。对于 Visual C++,目标文件的后缀是.obj;对于 GCC,目标文件的后缀是.o。

链接就是一个“打包”的过程,它将所有的目标文件以及系统组件组合成一个可执行文件。

三、运行环境 程序执行的过程: 1. 程序必须载入内存中。在有操作系统的环境中:一般这个由操作系统完成。在独立的环境中,程序 的载入必须由手工安排,也可能是通过可执行代码置入只读内存来完成。 2. 程序的执行便开始。接着便调用main函数

3. 开始执行程序代码。这个时候程序将使用一个运行时堆栈(stack),存储函数的局部变量和返回 地址。程序同时也可以使用静态(static)内存,存储于静态内存中的变量在程序的整个执行过程 一直保留他们的值。

4. 终止程序。正常终止main函数;也有可能是意外终止。

总结

 如果大家还想进一步了解程序的编译,大家可以看《程序员的自我修养》这本书,这里面主要是讲解编译链接执行是如何实现的。

 



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3