技术问题-编译性语言和解释性语言

741 阅读5分钟

编译型语言

编译型语言和汇编语言一样,有一个负责翻译的程序来对我们编写的源代码进行转换,生成相对应的可执行代码。这个过程说得专业一点,就称为编译(Compile),而负责编译的程序自然就称为编译器(Compiler)。

如果我们写的程序代码都包含在一个源文件中,那么通常编译之后就会直接生成一个可指定文件,我们就可以直接运行了。但是对于一个比较复杂的项目,我们为了方便管理,通常会把代码分散在各个源文件中,作为不同的模块来组织。这时编译各个文件时就会生成目标文件(Object File)而不是前面说的可执行文件。

一般一个源文件的编译都会对应一个目标文件,这些目标文件里面的内容基本上已经是可执行代码了,但由于只是整个项目的一部分,所以我们还不能直接运行。等到所有的源文件都编译完成,我们就可以最后把这些半成品的目标文件打包成一个可执行文件了。这个工作由另一个程序负责完成,由于这个过程是把包含可执行代码的目标文件连接装配起来,所以又称为链接(Link),而负责链接的程序自然就称为链接程序(Linker)了。

链接程序除了链接目标文件外,可能还要管理各种资源,像图标文件、声音文件什么的,又要负责去除目标文件之间的冗余重复代码等等,其实链接程序也很不容易呢。但是链接完成之后,一般就可以得到我们想要的可执行文件了。

解释型语言

从字面上看,编译和解释都有翻译的意思,他们的区别就在于翻译的时机安排不太一样。

打个比方,假如你打算阅读一本外文书,而你不知道这门外语,那么你可以找一名翻译,给他足够的时间让他从头到尾把整本书翻译好,然后把书的母语版交给你阅读。或者你也可以立刻让这名翻译辅助你阅读,让他一句一句地给你翻译,如果你像往回看某个章节,他也得给你重新翻译。这两种翻译的方式,前者就相当于编译型语言,后者就相当于解释型语言。

编译型语言就是一次性把所有的代码转换成机器语言,然后写成可执行文件。

解释性语言则是在程序运行的前一刻还只有源代码没有可执行文件,程序每执行到源代码的某一条指令,就会有一个称为解释程序的外壳程序将源代码转换成二进制代码以供执行,也就是说,要不断地解释、执行、解释、执行、解释、执行。。。像极了人生。因此,解释型语言是离不开解释程序的。像早期的BASIC就是一门经典的解释性语言,要执行BASIC程序,就要进入BASIC环境,然后才能加载程序源文件和运行。

编译型语言和解释型语言的比较

因为解释型语言编写的程序总是以源代码的形式出现,因此只要有相对应的解释器的话,移植几乎不成问题。编译型语言编写的程序虽然源代码可以移植,但前提是必须针对不同的环境分别进行编译,对于复杂的工程来说,的确是一个不小的时间消耗,更何况可能有些细节的地方还是要修改源代码。

而且,解释型语言因为省却了编译的步骤,修改调试会十分方便,编辑完毕之后即可立即运行,不必像编译型语言一样每次小小改动都要耐性等待漫长的Compling。。。Linking。。。这样的编译链接过程。不过凡事有利有弊,由于解释型语言是将编译的过程放到执行过程种,这就决定了解释型语言注定要比编译型语言慢上一大截,像几百倍的速度差距也是不足为奇的。

编译型语言和解释型语言各有各的优点和缺点。前者由于程序执行速度快,同等条件下对系统要求较低,因此开发操作系统、大型应用程序、数据库系统等时都会采用它,像C/C++、Pascal/Object Pascal(Delphi)、VB等语言基本都可视作编译型语言。而一些网页脚本、服务器脚本和辅助开发接口这样,对速度要求不高,对不同系统平台间的兼容性有一定要求的程序则通常使用解释型语言,像Java(好好想想为什么,嘿嘿)、JavaScript、VBScript、Perl和Python等就是解释型语言。

因为编译型语言和解释型语言各有优缺点又相互对立,因此很多新兴语言都有把两者折衷结合起来的趋势。例如Java语言虽然比较接近解释型语言的特征(要依赖JVM虚拟机运行),但在执行之前已经预先进行过一次预编译,生成的代码是介于机器码和Java源代码之间的中介代码,运行时由JVM(Java的虚拟机平台,可视为解释器)解释执行。它既保留了源代码的高抽象、可移植的特点,又已经完成了对源代码的大部分预编译工作,所以执行起来比纯种解释型语言要快很多。

随着设计技术和硬件的不断发展,编译型语言和解释型语言的界限正在不断变得模糊。

总结

编译型语言:执行速度快、效率高、依靠编译器、跨平台性较差。

解释型语言:执行速度慢、效率低、依靠解释器、跨平台性能好。