C语言程序从编写到运行历经的几个阶段 |
您所在的位置:网站首页 › 开发汇编语言程序步骤包括哪些 › C语言程序从编写到运行历经的几个阶段 |
C语言程序从编写到运行历经的几个阶段
一 前言
在完成 .c 或 .cpp 文件的编写后,我们通常直接 gcc 或 g++ 后接文件名,就可以在当前文件夹下生成 a.out 可执行文件, 之后输入 ./a.out 即可执行该二进制可执行文件。 但实际上C语言程序从编写到运行,这期间的经历并不是这么简单,那么现在小编就带领大家探索,这期间具体有哪几个步骤? 一 过程简介
执行 gcc -E hello.c > hello.i 命令后,我们仅仅执行预编译操作,生成一个.i 文件 (这个文件是我们最后还可以读得懂的文件了,我们可以打开这个文件,仔细观察程序出现了哪些变化) 那么预处理阶段都进行了哪些操作呢? 对所有以 # 开头的语句进行处理,其中包括我们熟知的:#define、#include 、条件编译指令#ifdef等。删除所有的“/**/”和“//”注释。添加行号和文件名标识,方便编译器产生的调用以及当出现编译错误或者是警告时可以显示行号。保留所有的 #pragma 编译指令这里小编想着重阐述的是第一部分!!! 程序中以“#include”开头的语句都会被替换成相应头文件中的内容 (也就是说,项目中不论是自己写的 被#include ""引用的.h 头文件还是系统自带的#include 头文件,在预处理阶段阶段之后都会消失,并且这个过程是递归进行的,因为被包含的文件还有可能包含了其他文件,同时为了避免头文件的重复包含,我们引入了#ifdef,#ifndef等条件编译指令,这里就不细说)。 此外程序中的#define 定义的宏在使用的地方都会进行替换 (大家不要小看宏定义,这决不仅是 #define PI 3.14之后进行使用这么简单) 关于宏定义的其他操作如下: 使用 -S选项,编译器执行完编译阶段就结束,最后形成 .s 文件 应该说编译阶段是整个程序从C到机器语言翻译过程的核心,我们之前学习的编译原理这门课中讲到的词法分析、语法分析、语义分析以及之后的优化等其他操作, 其实就是在这个阶段执行的。 四 汇编阶段使用 -c 选项,编译器执行完汇编阶段就结束,形成 .o (windows下为 .obj ) 对象文件。 其中汇编器将会汇编代码转换为机器可识别的机器代码,之前项目中有几个 source.c 文件,此时就会出现几个对象文件 五 链接阶段前一个阶段我们得到了若干个对象文件,现在我们要做的就是将这几个对象文件链接起来,形成最后的可执行文件。 (这其中还涉及到静态链接库和动态链接库的概念,若想了解,请点击我) (20220311更新) 静态链接库和动态链接库代码演示:静态链接和动态链接的区别在于:对函数库的链接是在编译期完成还是程序运行时期完成,若是编译期间则是静态链接,对应的函数库就是静态链接库 (linux下为.a文件,win下为.lib文件),若是在运行时期完成,则为动态链接,对应的函数库就是动态链接库 (linux下为.so文件,win下为.dll文件),不论静态链接库还是动态链接库,都是由若干个对象文件构成的。 闲话不多说,我们先写一些演示代码 (先演示静态链接库后演示动态链接库),如下分别创建:add.h、add.cpp、sub.h、sub.cpp、main.cpp 五个文件,文件内容如下: /* sub.h 文件内容 */ #ifndef _SUB_H #define _SUB_H int sub(int, int); #endif /* sub.cpp 文件内容 */ #include "sub.h" int sub(int x, int y) { return x - y; } /* add.h 文件内容 */ #ifndef _ADD_H #define _ADD_H int add(int, int); #endif /* add.cpp 文件内容 */ #include "add.h" int add(int x, int y) { return x + y; } /* main.cpp 文件内容 */ #include "sub.h" #include "add.h" #include using namespace std; int main() { cout |
今日新闻 |
点击排行 |
|
推荐新闻 |
图片新闻 |
|
专题文章 |
CopyRight 2018-2019 实验室设备网 版权所有 win10的实时保护怎么永久关闭 |