1
codeaqua 2016-01-31 20:55:08 +08:00 1
编译器: 编译完就可以扔了,运行不依赖它;
解释器: 你要运行,必须依赖它; |
2
zhuangzhuang1988 2016-01-31 21:47:56 +08:00
扯啥本质。。 浪费时间。。
|
3
donge 2016-01-31 22:00:34 +08:00
|
4
yuechen323 2016-01-31 22:47:52 +08:00 via iPhone
根本区别是 运行时候,解释型需要将程序解释成机器懂的机器码来运行 费了一道手 而编译型在运行之前就已经让编译器给程序编译成机器码了 所以更快 如 c cpp
|
5
Lab 2016-01-31 23:08:55 +08:00
编译器:在代码运行之前,生成目标平台指令,可脱离编译器而独立运行。
解释器:在代码运行过程中,生成目标平台指令,不可脱离解释器,无法独立运行。 编译器: C 、 C++等 解释器: Python 、 Ruby 、 PHP 等。 |
6
seeker 2016-01-31 23:28:50 +08:00
有没有 runtime 的区别
|
7
lightening 2016-02-01 00:15:13 +08:00 via iPad
@yuechen323 那 java 编译器算啥?
|
8
fy 2016-02-01 01:41:07 +08:00
@Lab 动态语言中其实界限很模糊。
java 分编译器和 VM ,会编译出二进制文件 python 也是编译成字节码,有 VM ,有时候会输出为 pyc lua 同样是编译 + VM 执行 然而这些都并没有什么卵用 |
9
dorentus 2016-02-01 01:58:20 +08:00 via iPhone
榨汁机和电饭锅的本质区别是啥?
|
10
MiguelValentine 2016-02-01 02:09:49 +08:00
编译器是工具 解释器是环境
|
11
neoblackcap 2016-02-01 03:44:19 +08:00
@lightening Java 就是编译型的,跟 C/C++之类的没区别,只不过一个是输出 x86/arm 平台的本地二进制代码,一个是输出可以运行在符合 JVM 标准的虚拟机字节码而已。
|
12
pynix 2016-02-01 03:48:11 +08:00
现在的 VM 基本都有 jit 了。
|
13
lightening 2016-02-01 04:32:18 +08:00 via iPad
@neoblackcap 那么它也不符合编译后可以独立运行这条
|
14
minsheng 2016-02-01 06:22:46 +08:00 1
可以把解释器分成两种,一种是基于语法树的解释器,一种是基于字节码的解释器。
举个例子, 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 也可以用硬件实现。我认为,只要记得基于语法树的解释和基于字节码的解释这一区别即可。 |
15
Perry 2016-02-01 06:59:54 +08:00 via iPhone
上一下 Computer Architecture 就能理解了吧
|
16
forrestchang 2016-02-01 07:44:05 +08:00
|
19
hazard 2016-02-01 09:46:48 +08:00
offline 和 online 的区别
|
20
airqj 2016-02-01 10:10:40 +08:00 via Android
你是想不管冷热为省时间一次性穿好衣服,还是冷的时候穿热的时候脱?
|
21
tiancaiamao 2016-02-01 12:08:13 +08:00
推荐 《 Lisp in Small Pieces 》
|
22
louk78 2016-02-01 14:58:57 +08:00
编译器是将高级语言翻译为二进制文件
解释器是将 PE 二进制翻译为机器指令 |
23
rainex 2016-02-01 18:19:56 +08:00
编译器:源代码->中间代码-> [可执行代码] ->操作系统载入自己执行
解释器分两种: 第一种:源代码-> [中间代码] ->操作系统载入解释器执行 第二种:源代码->操作系统载入解释器执行 也有把第二种解释器算作编译的, C#、 Java 乃至 zend 跑的 php 都类似的机制,但本质上还是一种解释执行。 |
24
twd2 2016-02-01 19:19:55 +08:00
编译器就是把源代码一起都翻译成机器看得懂的语言,然后这一坨交给机器来运行。
解释器就是读取一段源代码,翻译成机器看得懂的语言,让机器执行,然后再处理下一段...... |
25
rainex 2016-02-01 20:04:35 +08:00
修正 23 楼:
编译器:源代码->中间代码-> [可执行代码] ->操作系统载入自己执行 解释器分两种: 第一种:源代码-> [中间代码] ->操作系统载入解释器执行 第二种:源代码->操作系统载入解释器执行 也有把 [第一种] 解释器算作编译的, C#、 Java 乃至 zend 跑的 php 都类似的机制,但本质上还是一种解释执行。 ps :不能修改的 bbs ,嗯 |
26
jybox 2016-02-01 20:32:46 +08:00
我现在觉得可能编译执行和解释执行是一个程度问题,取决于语言的设计和实现上,在编译阶段和运行阶段之间建立了多么强的抽象或隔离。
|
27
FlowMEMO 2016-02-01 21:09:40 +08:00
Engineering a Compiler 书中的说法是“ An interpreter takes as input an executable specification and
produces as output the result of executing the specification.”,重要的是产生结果。 书中举例将 PostScript 转换成图像的东西是解释器。从这个角度来看,给定 html 和 css ,浏览器的排版过程也可以看作是解释。 |
28
libook 2016-02-01 23:36:38 +08:00
我上学的时候理解的是:编译器就是把源代码转换成机器码的软件,运行的时候直接运行机器码就可以了,不再依赖编译器;解释器就是一个懂得源代码的软件,运行这个软件然后直接让它按照源代码做事,每一个源代码指令编译器都懂得是什么具体的操作,并能立即执行。
如果拿人来做比喻,就是:小 A 跟编译器说想吃螃蟹,于是编译器教会了小 A 如何剥螃蟹;小 B 跟解释器说他也想吃螃蟹,解释器就帮他剥好了螃蟹。这大概就是编译器和解释器的区别吧。 当然实际的编译器和解释器的原理比这要复杂得多,你若真想究其毫厘还是要专门拿几个编译器和解释器来研究一下。 |
29
cs202 2016-02-02 07:09:30 +08:00
|
30
zxgngl OP 编译是“转换变换”;解释是“赋予意思”。
|