解释器和编译器是如何工作的?

84

解释器和编译器的工作原理有何不同?它们之间的区别是什么?

8个回答

71

编译器

编译器是最早被开发的翻译程序。原理很简单:你写好程序,然后将其交给编译器进行翻译。接着你运行翻译后的程序。

解释器

解释器同样是一种将高级语言翻译成低级语言的程序,但它是在程序运行时才进行翻译的。你使用文本编辑器或其他类似工具编写程序,然后指示解释器运行该程序。解释器一次处理一行程序代码,先翻译第一行并运行它,再翻译第二行并运行它,以此类推。

编译器的特点:

  • 需要花费大量时间分析和处理程序代码
  • 生成的可执行文件是某种形式的机器专用二进制代码
  • 计算机硬件对生成的代码进行解释(执行)
  • 程序执行速度较快

解释器的特点:

  • 相对于编译器,只需花费较少时间来分析和处理程序代码
  • 生成的代码是一些中间代码的形式
  • 生成的代码由另一个程序进行解释
  • 程序执行速度相对较慢

1
所以C#同时使用编译器和解释器吗? - developer
10
不正确。这两种语言都是编译型和解释型的。 - Matthew H
@开发者,所有的编程语言都是编译和解释的。它们可以通过虚拟机或真实机器进行解释(在编译后),也可以通过特殊程序(称为解释器)在语法正确、形式定义明确的语言上进行解释。 - Aniket Inge
2
@Aniket 不,目标代码不会进行任何解释。如果您将程序编译成机器可以理解的东西,则不需要解释器。此外,问题的重点是编译器生成的目标代码与例如Java编译器生成的中间代码(例如字节码)之间的区别,后者每次运行时都由真正的解释器进行解释。 - chesscov77
1
直译:通常来说,解释器并不一定逐行工作。绝大多数的解释器并非如此。同样也并不普遍地认为解释器会生成低级别代码:有些解释器会遍历抽象语法树(不产生任何代码),有些解释器会生成字节码然后解释执行它,还有些解释器则会实时编译成机器码。通俗翻译:解释器通常不是一行一行地执行代码,大部分的解释器都不是这样的。同时,解释器也不一定只能产生底层代码,有些解释器可以遍历语法树(不需要产生代码),有些解释器可以生成字节码并执行,还有些解释器可以即时编译成机器码。 - sepp2k
显示剩余2条评论

37
  • Compilers typically produce faster executing code than interpreters.
  • Interpreted code can be slower due to the overhead of interpreting each instruction at runtime.
  • Usage

    • Compilers are generally used for large projects where performance is important.
    • Interpreters are often used for small scripts and when ease of use is more important than performance.
  • 编译器需要很长时间将源程序翻译为本机机器代码,但随后的执行速度很快。
  • 解释器立即开始执行源程序,但执行速度较慢。
  • 解释性编译器

    解释性编译器是编译器和解释器之间的一个很好的折衷方案。它将源程序转换成虚拟机器码,然后进行解释。

    解释性编译器结合了快速翻译和相对快速的执行,前提是:

    • 虚拟机器码低于源语言,但高于本机机器码
    • 虚拟机指令具有简单的格式(可以快速被解释器分析)

    示例:JDK为Java提供了一个解释性编译器。


    5
    一个解释器一次执行一条源代码指令,但不翻译源代码。我认为解释器同时进行翻译和执行两个动作,而不仅仅是像你解释的那样只执行。除此之外,这个解释很清晰完美,加一分。 - JAVA

    24

    编译器,将一种计算机语言的源代码转换为另一种语言。

    解释器,直接执行源代码(通常在其自己的虚拟机中)。

    alt text
    (来源:Answers.com)

    通常解释器的性能代价较高。


    几乎所有的解释器都执行编译后的字节码,而一些模拟器则执行编译后的机器码。只有当被解释的指令相对于获取开销来说非常简单时,解释才会“性能昂贵”。 - user207421
    C# 和 VB 呢?它们在你的图表中属于哪个部分? - variable

    19
    什么是解释器和编译器的区别?

    enter image description here

    编译器会先扫描整个程序,然后将其翻译成机器码,计算机处理器再执行它。解释器会将一个语句翻译成机器语言,执行它,然后继续下一个语句。例如,编译器会一次性给出几乎所有的错误,但解释器会一直运行,直到您写错的指令为止。
    “解释器/编译器是如何工作的?”

    enter image description here

    • 与编译语言不同,编译语言提前被翻译成机器语言(正确)。
    • 解释语言在运行时被翻译(正确)。
    • dBASE和BASIC解释器(中间)翻译原始源代码。
    • Java和Visual Basic(左侧)解释器翻译字节码,这是从原始源代码编译的中间语言。

    来源


    “一次只处理一行”是不正确的。大多数解释器会将代码预编译成p-code,然后逐条执行该p-code指令。 - user207421
    1
    解释器不会“翻译字节码”。它们会执行它。有一些基本实现可执行字节码,而非源代码。 - user207421

    7

    区别与工作原理

    问:编译器和解释器用于什么?

    答:大多数程序都是用高级语言编写的(如c#、java...)。 高级语言包含易于理解的单词和短语。 另一方面,计算机(截至我写这篇文章的时候)只能理解二进制/机器码,即0和1。 因此,我们需要将高级代码转换为源代码(机器码/二进制)。 因此有了“转换”这个词。

    因此,我们可以得出结论:编译器/解释器的工作是将高级代码转换为机器码。

    但两者在“翻译”代码的方式上有所不同

    区别:

    编译器:

    将源代码转换为某种中间形式。 对于静态语言,编译器通常将源代码转换为汇编语言,该汇编语言通常不会存储到磁盘中,然后调用汇编器将汇编语言转换为二进制代码,该二进制代码通常存储为对象文件(.o或.obj后缀),然后链接器被调用以将对象文件链接到二进制可执行文件上。 还常常将编译,汇编和链接的整个过程称为编译。 因此,您可以将gcc称为编译器,但实际上它会调用cc1来编译,as来汇编,ld来链接。

    解释器:

    具有中间字节码形式的语言,源代码首先被转换为字节码,这个过程可以称为编译,javac就是一个例子。字节码不能在主机上运行,需要一个程序(从操作系统的视角来看,实际上是进程)将字节码解释为主机,这个程序称为解释器,比如java。一些语言,如Python,使用单个程序执行编译和解释工作

    ——均摘自:https://www.quora.com/What-are-the-differences-between-a-compiler-an-interpreter-and-an-assembler-Provide-examples

    比较

    解释器

    • 分析源代码所需时间较短,但总体执行时间较慢。
    • 不生成中间目标代码,因此内存效率高。
    • 持续翻译程序,直到遇到第一个错误为止,此时它停止。 因此,调试很容易。

    编译器

    • 分析源代码所需时间较长,但总体执行时间相对较快。
    • 生成中间目标代码,进一步需要链接,因此需要更多内存。
    • 只有在扫描整个程序后才生成错误消息。 因此,调试比较困难。

    — 来自:https://www.programiz.com/article/difference-compiler-interpreter

    语言示例

    解释型

    • Python
    • Ruby
    • PHP
    • JAVA(全能)
    • Perl
    • R
    • Powershell

    编译型

    • C
    • C++
    • C#
    • Objective-C
    • SWIFT
    • Fortran

    1
    大多数编译器不会生成汇编语言。链接不意味着更多的内存。源代码解释器存在。C#是解释性的,事实上Java和C#都是编译和解释两用的。C和C++也有解释版本,Fortran也是如此。 - user207421

    0

    看看PLAI这本书,我发现它是最好的动态语言实现入门:

    编程语言:应用与解释 (c) Shriram Krishnamurthi

    这本书以在Scheme(dr.Racket)中编写动态语言解释器为中心,使用它,您可以为任何语言编写自己的解释器,并添加一些关于OOP的提示。

    还有SmallTalk和SOM:Simple Object Machine:

    所有现代解释器都包含编译器:将高级元素编译成低级但可移植的字节码,或使用JIT将其编译成机器代码到RAM中。

    附注:如果有人想在Python上编写SmallTalk系统,请通知我。


    1
    这个答案的90%只是广告。 - user207421

    0
    编译器和解释器的区别是什么?
    直截了当地说:
    - 编译器 将人类可读的源代码转换成机器码,让计算机可以读取和执行。 - 解释器 像是一个模拟计算机的程序,直接读取和执行源代码。

    0
    编译器 - 编译器将源语言翻译成目标语言,然后目标语言接受输入并产生输出。 编译器通过编译源代码生成目标代码 然后目标代码接受输入并产生输出 解释器 - 解释器直接接受输入和源代码并产生输出,而不是生成目标代码。 解释器使用源程序将输入映射到输出 因此,编译器生成的面向机器语言的程序比解释器更快地将输入映射到输出。但是,由于解释器逐行执行源程序,因此它比编译器提供更好的错误诊断。
    参考资料 - 《编译原理》(龙书) by Aho

    网页内容由stack overflow 提供, 点击上面的
    可以查看英文原文,
    原文链接