编译器与解释器的根本区别是什么?

2016-01-31 20:36:27 +08:00
 zxgngl
11505 次点击
所在节点    程序员
30 条回复
codeaqua
2016-01-31 20:55:08 +08:00
编译器: 编译完就可以扔了,运行不依赖它;
解释器: 你要运行,必须依赖它;
zhuangzhuang1988
2016-01-31 21:47:56 +08:00
扯啥本质。。 浪费时间。。
donge
2016-01-31 22:00:34 +08:00
yuechen323
2016-01-31 22:47:52 +08:00
根本区别是 运行时候,解释型需要将程序解释成机器懂的机器码来运行 费了一道手 而编译型在运行之前就已经让编译器给程序编译成机器码了 所以更快 如 c cpp
Lab
2016-01-31 23:08:55 +08:00
编译器:在代码运行之前,生成目标平台指令,可脱离编译器而独立运行。
解释器:在代码运行过程中,生成目标平台指令,不可脱离解释器,无法独立运行。

编译器: C 、 C++等
解释器: Python 、 Ruby 、 PHP 等。
seeker
2016-01-31 23:28:50 +08:00
有没有 runtime 的区别
lightening
2016-02-01 00:15:13 +08:00
@yuechen323 那 java 编译器算啥?
fy
2016-02-01 01:41:07 +08:00
@Lab 动态语言中其实界限很模糊。

java 分编译器和 VM ,会编译出二进制文件
python 也是编译成字节码,有 VM ,有时候会输出为 pyc
lua 同样是编译 + VM 执行

然而这些都并没有什么卵用
dorentus
2016-02-01 01:58:20 +08:00
榨汁机和电饭锅的本质区别是啥?
MiguelValentine
2016-02-01 02:09:49 +08:00
编译器是工具 解释器是环境
neoblackcap
2016-02-01 03:44:19 +08:00
@lightening Java 就是编译型的,跟 C/C++之类的没区别,只不过一个是输出 x86/arm 平台的本地二进制代码,一个是输出可以运行在符合 JVM 标准的虚拟机字节码而已。
pynix
2016-02-01 03:48:11 +08:00
现在的 VM 基本都有 jit 了。
lightening
2016-02-01 04:32:18 +08:00
@neoblackcap 那么它也不符合编译后可以独立运行这条
minsheng
2016-02-01 06:22:46 +08:00
可以把解释器分成两种,一种是基于语法树的解释器,一种是基于字节码的解释器。

举个例子, 3+4*5 ,基于语法树的解释器大概会是这样的:
data Expr = Lit Integer | Add Expr Expr | Mul Expr Expr

-- 构造语法树
ast :: Expr
ast = Add (Lit 3) (Mul (Lit 4) (Lit 5))

-- 解释器,使用模式匹配
eval :: Expr -> Int
eval (Lit x) = x
eval (Add e1 e2) = eval e1 + eval e2
eval (Mul e1 e2) = eval e1 * eval e2

而基于字节码的则会先把源代码翻译成一段字节码:
% 0 = 3
%1 = 4
%2 = 5
%3 = mul i32 %1, %2
%4 = add i32 %0, %3

上述代码为 LLVM 中间表示,每个 %x 代表一个虚拟寄存器,有无数个虚拟寄存器。解释器会先把这段代码翻译成只使用一定数量的寄存器的形式,比如说:
%0 = 4
%1 = 5
%0 = mul i32 %0 %1
%1 = 3
%0 = add i32 %01 %1

这里只用了两个寄存器。接着,就可以解释执行这段代码。

另一种做法就是基于栈的解释器,大概长这样:
push 3
push 4
push 5
mul ;此时栈顶是 4 与 5
add ;此时栈顶是 3 与 20

据说这种方法实现起来比较简单,但是没有基于寄存器的解释方法来得快。如果没有记错的话, Lua 就是基于寄存器的解释,而 JVM 则很长一段时间都基于栈。

所谓的编译器,无非就是只完成了到字节码的翻译步骤,将执行交给硬件完成。不过编译器这个概念依然没有意义,因为硬件也是可以模拟的,比如说 Bochs ,比如说 QEMU 。难不成我们把 GCC 编译出来的代码换个环境之行,它就变成了解释器了?同理, JVM 也可以用硬件实现。我认为,只要记得基于语法树的解释和基于字节码的解释这一区别即可。
Perry
2016-02-01 06:59:54 +08:00
上一下 Computer Architecture 就能理解了吧
forrestchang
2016-02-01 07:44:05 +08:00
可以看一下《程序设计语言——实践之路》这本书的第一章。

R 大的这篇文章也可以参考一下: http://rednaxelafx.iteye.com/blog/492667
gzxultra
2016-02-01 08:35:50 +08:00
@Perry 体系结构并不讲这个啊
Perry
2016-02-01 08:52:59 +08:00
@gzxultra 看错了 还以为是问 compiler 和 assembler 的区别
hazard
2016-02-01 09:46:48 +08:00
offline 和 online 的区别
airqj
2016-02-01 10:10:40 +08:00
你是想不管冷热为省时间一次性穿好衣服,还是冷的时候穿热的时候脱?

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/254651

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX