C语言程序编译过程详解

编译程序:

我们知道,计算机只能识别0和1,而我们的程序代码使用高级语言编写的,所以,要想被计算机识别并按照我们的要求工作,就必须将其翻译成等价的0/1序列。当我们编写好程序后并发出指令,在没有语法错误等异常情况下,计算机便会自动地将我们的源代码一步一步地进行处理,最终得到0/1序列。

    程序的编译过程可分为如下4个大的步骤:
    (1)预处理;
    (2)编译;
    (3)汇编;
    (4)链接。

源文件(name.c)–(预处理)–>name.i–(编译)–>name.s–(优化程序)–>优化后的程序文件–(汇编)–>name.o–(链接)–>可执行文件

1.预处理

(1)宏替换
对于如#define name tokenstring,#undef等,对于#define,预处理所要做的是将程序中所有出现name的地方(包含在双引号中的name除外)用tokenstring替换。对于#undef,则取消对某个宏的定义,是以后name的出现不在被替换。

以下是一个有趣的宏替换例子:

#include<stdio.h>
#include<stdlib.h>

#define X 3
#define Y X*2
#undef X
#define X 2

int main()
{
    int z = Y;
    printf("%d\n", z);

    system("pause");
    return 0;
}

想想输出的结果是什么呢?6还是4?仔细分析,在预处理的时候,主函数中Y的地方被X*2替换,宏#undef将取消对#define X 3中X的宏定义,有效的宏定义应该为#define X 2。所以准确的说,主函数中Y的地方应该被2*2替换。

(2)头文件包含
如#include或者#include”filename”等。在头文件中一般中伪指令#define定义了大量的宏,同时包含有各种外部符号的声明。采用头文件的目的主要是为了使某些定义可以供多个不同的C源程序使用,这样,就不必再文件中重现定义。预编译的时候,将出现了的头文件的定义都加入该文件中,以供编译程序对其进行处理。包含到c源程序的头文件可以是系统提供的,这些文件一般别放在/usr/include目录下,使用文件名写在<>中。另外,开发人员自己定义的头文件一般与c源程序放在同一目录下,文件名写在” “中。

(3)条件编译
如#ifdef、#ifndef、#else、#elif、#endif等,这些伪指令使得开发人员可以定义不同的宏来决定编译程序需要处理哪些代码,而将不需要的代码段裁剪掉。

(4)特殊符号处理
预编译程序可以识别一些特殊的符号,如预处理指令FILE、LINE、TIME等(可以看我之前的博文:预定义符号简述)。已编译程序对于在源程序中出现的这些串讲用合适的值进行替换。

预编译程序所完成的基本上是对源程序的“替换”工作,经过替换宏,生成一个没有宏定义、没有条件编译、没有特殊符号的.i文件。这个文件与未进行预编译的.c文件意义是相同的,但是内容不同。

2.编译阶段

编译过程需要做的工作就是通过词法分析和语法分析,在确认所有的指令都符合语法规则之后,将其翻译成等价的中间代码表示或汇编代码,即.s文件。

3.汇编过程

汇编过程有汇编器完成,将汇编代码转换成机器可以执行的命令,每一个汇编语句几乎都对应一条机器指令。经过汇编过程最终得到相应的目标文件,即.o文件,该文件中存放的是与源程序等效的目标机器语言代码。通常一个目标文件至少由两个段组成:代码段和数据段。代码段中包含的主要是程序的指令,该段一般是可读和可执行的,但一般却不可写;数据段中主要存放的是程序中要用到的各种全局变量或者静态的数据,该段一般是可读、可写和可执行的。

4.链接过程

通过调用连接器来链接程序运行需要的一大堆目标文件,最终生成一个完整的可执行文件。链接主要包括地址和空间分配、符号决议、重定位等。链接分为静态链接和动态链接。静态链接:是指在编译阶段直接把静态库加入到可执行文件中去;动态链接:是指链接阶段仅仅只加入一些描述信息,而程序执行时再从系统中把相应动态库加载到内存中。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值