编译器与解释器的区别

3

那么,让我看看我是否清楚明白了。

  1. 我们说编译器和解释器之间的区别在于解释器将高级指令翻译成中间形式,然后执行它。 [我认为编译器也将高级指令翻译成中间形式,但此时它生成的是目标代码而不是执行它,对吗?]

  2. 解释器一次读取一个指令或一行源代码,将其转换为机器码并执行。 [解释器本身并不将代码转换为机器码,它使用自己预编译的函数来评估指令(在解析后)。例如,高级语言中的Add表达式将使用解释器的add函数进行评估,该函数已经被预先编译了,对吗?]


在第1点中,您第二次提到“interpreter”时,是不是应该指“compiler”? - Eric
不,Eric,我真的是指解释器。 - utxeee
这个回答解决了你的问题吗?解释器/编译器是如何工作的 - Adam Millerchip
3个回答

3
关键区别在于:解释器在运行源代码时处理它。它不会将源代码转换为机器代码,而是使用自己的代码来实现源代码的指示。编译器将源代码转换为可直接运行的机器代码。
并非所有编译器都与执行过程分离。例如,大多数Java运行时包括“JIT编译器”,它在需要时编译Java代码。
你可以有介于两者之间的东西。基本上,可以先使用类似编译的过程将源代码转换为更小且更易于解释的内容。然后可以解释这个已编译的输出。(例如,第一遍可以将“if”转换为53,“else”转换为54,“for”转换为55等——这将使解释器无需处理变长字符串,因为代码实际上并不涉及字符串。)

1

我同意第一个观点,尽管解释器不一定在一次处理一行代码(它可以根据整个代码的知识进行优化)。

我认为第二个观点略有偏差:编译器确实会创建“机器码”(可能是JVM的字节码)。解释器根据输入执行其自身程序的部分(到目前为止与编译器相同),这些执行的部分执行描述输入中的计算(而不是执行计算以计算所需的机器码)。

通过编译器生成将在执行时被解释的代码(以基于编译时不可用的因素提供运行时优化),两者之间的界限是可以模糊的。


嗨,Attila,如果我理解正确,您同意我关于第二点的观点吗? - utxeee
并不完全正确:解释器(主动)没有进行执行代码的翻译:这是在编译解释器时完成的(假设它本身没有被解释)。解释器使用其现有的代码(已经是机器码)来执行所需的计算。这基本上就是方括号中的内容,但并不是粗体部分所说的。 - Attila
粗体部分不是我写的,我在某处读到它。我只是将其标记出来,因为我不同意。我的话只是括号里的那些。因此,你真的同意我:D - utxeee

0

关于(1),你是对的。

至于(2),解释器不需要逐条读取源代码,因为当解释包含循环的代码时,这样做太昂贵了。更有可能的是,它会读取整个表达式、语句、函数甚至源文件,将其转换为中间格式并进行评估。

请注意,编译器和解释器都不需要在任何时候生成机器代码;许多编程语言,包括Java、Python以及旧的语言如Prolog,通常被编译成虚拟机字节码。在Python和Prolog中,“解释器”通常是一个组合的字节码编译器/字节码解释器。

我所知道的关于编译和解释的最好介绍是SICP的第4章和第5章,它从讨论一个非常简单的解释器开始,并逐步改进直到成为一个完整的编译器。


嗨,larsman,但是当我们使用gcc时,它确实会生成机器代码,对吧? - utxeee
@user1334379:是的,GCC生成机器码,所有主要的C和C++编译器都是如此。有趣的是,GCC的Java编译器GCJ也可以生成机器码,这与其他Java编译器不同。 - Fred Foo

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