C 语言编译原理简介
刚开始接触编程的时候,只知道照书敲敲代码,一直都不知道在windows 平台下的程
序代码经过鼠标那样点击几下,之后程序的结果就会在那个黑色的屏幕上,这期间到底发生
了些什么。现在找了个机会将C 语言的编译原理的流程做一下小小的总结,这样也能为以
后我们进军linux 编程做一些准备,现在这里和大家一起分享分享。O(∩_∩)O~
讲到编译原理,我觉得首先我们得明白一些基本概念。
1. 编辑器:我们编写代码的一些窗口,如:记事本、word、notepad 等。
2. 编译器:检查用户代码的一些语法错误并且将其编译成汇编代码。
3. 汇编器:将编译出来的文件变成目标代码(windows 下的.obj 文件)
4. 连接器:将目标代码连接成为可执行文件(.exe),及双击就可以运行文件。
5. 集成开发环境(Integrated Development Environment,简称IDE):是用于程序开发环
境的应用程序,一般包括代码编辑器、编译器、调试器和图形用户界面工具。如:VC6.0、
C_Free 等。
好了,下面大家来看看整个过程吧:
Ok!现在是不是对程序的编译有一点概念了,O(∩_∩)O~。现在稍微总结一下编译的完整
C 源程序-- > 预编译处理 (.c) -- > 编译、优化程序( .s 、 .asm )-- > 汇
编程序 (.obj 、 .o 、 .a 、 .ko) -- > 链接程序( .exe 、 .elf 、 .axf 等)。
好了,现在我们就来逐条了解一下每个过程吧。
1. C 源程序
这个大家都清楚了,那就是自己编写程序代码。
2. 预编译处理 (.c)
它主要包括四个过程
a 、宏定义指令,如 #define N 6 , #undef 等。
对于前一个伪指令,预编译所要做的是将程序中的所有N 用6 替换,请大家注意
这里是替换,并不是像作为函数参数那样将 6 复制进 N 这个变量。对于后者,则将取消对
某个宏的定义,使以后出现的N 不再被替换。
b 、条件编译指令,如 #ifdef , #ifndef , #endif 等。
这些伪指令的引入使得程序员可以通过定义不同的宏来决定编译程序对哪些代码
进行处理。预编译程序将根据有关的文件,将那些不必要的代码过滤掉。这样就能在编译阶
段减少编译时间,提高效率,看看这是多好的指令。O(∩_∩)O~
c 、 头文件包含指令,如 #include "file.h" 或 #include <file.h> 等。
在头文件中一般用伪指令#define 定义了大量的宏(最常见的是字符常量),同时
包含有各种外部符号的声明。
采用这样的做法一来可以让我们直接调用一些复杂库函数;二来可以免去我们在写
程序时重复做一些定义声明工作的麻烦。试想一下,一旦我们写好头文件,那么以后要用到
相关模块就再也不用写这些函数了,直接#include 就OK 了,这可是一劳永逸啊,天大的
便宜呢,呵呵。
对了,这里顺便提一下#include<>与#include“”的区别。
#include<>:这条指令就是告诉编译器去系统默认的路径寻找相关文件。
#include”” :这条是告诉编译器先去源程序所在目录下寻找,如果没有就去系统默
认路径寻找。
d 、特殊符号,预编译程序可以识别一些特殊的符号。
例如在源程序中出现的LINE 标识将被解释为当前行号(十进制数),FILE 则被解
释为当前被编译的C 源程序的名称。预编译程序就是对在源程序中出现的这些特殊符号将
用合适的值进行替换。
大家注意到没,预编译阶段基本上是完成对源程序的相关代码进行替换,这样之后程序
的原意没有改变,就是代码的内容有所不同,这样为以后的编译做好准备,ok,第二阶段
完满结束,嘿嘿!
3. 编译、优化程序( .s 、 .asm )
经过上一阶段的处理,现在我们的程序已经没有宏定义,包含头文件等指令了,只
剩下一些变量,常量,关键字等,而编译的主要作用是检查这些代码的语法错误及将这些代
码编译成为汇编文件。
优化程序这是很复杂的,不仅和编译技术本身有关,还和目标板相应的硬件环境有
很大的关系。如下面的代码:
int a,b,c;
a = inWord(0x100);
b = a;
a = inWord (0x100);
c = a;
很可能被编译器优化为:
int a,b,c;
a = inWord(0x100);
b = a;
c = a;
也正是由于这种编译器优化作用才使关键字volatile 有了这么大的用武之地,当然这只是原
因之一。
4. 汇编程序 (.obj 、 .o 、 .a 、 .ko)
在这个阶段是将汇编代码翻译成目标文件,这时的文件已经是二进制代码了。在
windows 环境下文件的后缀名是.obj;而在unix 下则有是o、.a、.ko 等文件。
目标文件由段组成。通常一个目标文件中至少有两个段:
代码段:该段中所包含的主要是程序的指令。该段一般是可读和可执行的,但一般却
不可写。
数据段:主要存放程序中要用到的各种全局变量或静态的数据。一般数据段都是可读,
可写,可执行的。
5. 链接程序( .exe 、 .elf 、 .axf )
也许有人会有疑问,上面的目标代码已经是机器码了,也就是说CPU 可以识别这些
文件了,那为什么我们还要链接程序呢?大家想想我们是不是忘了点什么。。。对!那些被
包含的头文件,以及当我们的程序分布于很多源文件时,那么这些源文件该怎么处理呢,这
就是连接器的作用,它们被翻译成目标代码后需要被链接到一起才能被执行。这样就ok 了,
嘿嘿!
谈到函数库的链接,我们还需要了解点函数库的知识,函数库分静态链接库(又称静
态库*.lib)和链接动态库(又称动态库*.dll)。
静态库的链接在编译时会被编译进汇编文件,这样的操作会改变文件大小;而动态库
则是在执行时(双击运行),当需要动态库中的文件时才被链接到可执行文件的。
Ok!总结就到这里吧,当然C 语言的编译原理远不止这么简单!如果大家有兴趣
可以去找相关资料作更深而对研究,到时候也可以和其他人一起分享,我在这里只是对其流
程作一下简介,希望对大家能有所帮助吧,O(∩_∩)O~~~~
刚开始接触编程的时候,只知道照书敲敲代码,一直都不知道在windows 平台下的程
序代码经过鼠标那样点击几下,之后程序的结果就会在那个黑色的屏幕上,这期间到底发生
了些什么。现在找了个机会将C 语言的编译原理的流程做一下小小的总结,这样也能为以
后我们进军linux 编程做一些准备,现在这里和大家一起分享分享。O(∩_∩)O~
讲到编译原理,我觉得首先我们得明白一些基本概念。
1.
2.
3.
4.
5.
境的应用程序,一般包括代码编辑器、编译器、调试器和图形用户界面工具。如:VC6.0、
C_Free 等。
好了,下面大家来看看整个过程吧:
Ok!现在是不是对程序的编译有一点概念了,O(∩_∩)O~。现在稍微总结一下编译的完整
过程吧:
编程序 (.obj 、 .o 、 .a 、 .ko) -- > 链接程序( .exe 、 .elf 、 .axf 等)。
好了,现在我们就来逐条了解一下每个过程吧。
1.
2.
它主要包括四个过程
a 、宏定义指令,如 #define N 6 , #undef 等。
这里是替换,并不是像作为函数参数那样将 6 复制进 N 这个变量。对于后者,则将取消对
某个宏的定义,使以后出现的N 不再被替换。
进行处理。预编译程序将根据有关的文件,将那些不必要的代码过滤掉。这样就能在编译阶
段减少编译时间,提高效率,看看这是多好的指令。O(∩_∩)O~
包含有各种外部符号的声明。
程序时重复做一些定义声明工作的麻烦。试想一下,一旦我们写好头文件,那么以后要用到
相关模块就再也不用写这些函数了,直接#include
便宜呢,呵呵。
#include””
认路径寻找。
释为当前被编译的C 源程序的名称。预编译程序就是对在源程序中出现的这些特殊符号将
用合适的值进行替换。
的原意没有改变,就是代码的内容有所不同,这样为以后的编译做好准备,ok,第二阶段
完满结束,嘿嘿!
3.
剩下一些变量,常量,关键字等,而编译的主要作用是检查这些代码的语法错误及将这些代
码编译成为汇编文件。
很大的关系。如下面的代码:
int a,b,c;
a = inWord(0x100);
b = a;
a = inWord (0x100);
c = a;
很可能被编译器优化为:
int a,b,c;
a = inWord(0x100);
b = a;
c = a;
也正是由于这种编译器优化作用才使关键字volatile 有了这么大的用武之地,当然这只是原
因之一。
4.
在这个阶段是将汇编代码翻译成目标文件,这时的文件已经是二进制代码了。在
windows 环境下文件的后缀名是.obj;而在unix 下则有是o、.a、.ko 等文件。
目标文件由段组成。通常一个目标文件中至少有两个段:
不可写。
可写,可执行的。
5.
也许有人会有疑问,上面的目标代码已经是机器码了,也就是说CPU 可以识别这些
文件了,那为什么我们还要链接程序呢?大家想想我们是不是忘了点什么。。。对!那些被
包含的头文件,以及当我们的程序分布于很多源文件时,那么这些源文件该怎么处理呢,这
就是连接器的作用,它们被翻译成目标代码后需要被链接到一起才能被执行。这样就ok 了,
嘿嘿!
谈到函数库的链接,我们还需要了解点函数库的知识,函数库分静态链接库(又称静
态库*.lib)和链接动态库(又称动态库*.dll)。
静态库的链接在编译时会被编译进汇编文件,这样的操作会改变文件大小;而动态库
则是在执行时(双击运行),当需要动态库中的文件时才被链接到可执行文件的。
可以去找相关资料作更深而对研究,到时候也可以和其他人一起分享,我在这里只是对其流
程作一下简介,希望对大家能有所帮助吧,O(∩_∩)O~~~~