代码之家  ›  专栏  ›  技术社区  ›  chimeracoder

编译语言与解释语言

  •  247
  • chimeracoder  · 技术社区  · 16 年前

    我正在努力更好地理解这种差异。我在网上找到了很多解释,但它们倾向于抽象的差异,而不是实际的含义。

    我的编程经验大部分都是用cPython(动态的,解释的)和Java(静态的,编译的)。但是,我理解还有其他类型的解释和编译语言。除了可执行文件可以从用编译语言编写的程序中分发之外,每种类型都有什么优点/缺点吗?我经常听到人们争论解释语言可以交互使用,但我相信编译语言也可以有交互实现,对吗?

    11 回复  |  直到 9 年前
        1
  •  417
  •   Marie longkai    11 年前

    编译语言是指程序一旦编译,就在目标机器的指令中表达出来的语言。例如,源代码中的加法“+”操作可以直接转换为机器代码中的“加法”指令。

    解释语言是指指令不是由目标机器直接执行,而是由其他程序(通常是 用本机语言编写)。例如,解释器在运行时会识别相同的“+”操作,然后解释器用适当的参数调用自己的“add(a,b)”函数,然后执行机器代码“add”指令。

    您可以在编译语言的解释语言中做任何事情,反之亦然—它们都是图灵完备的。然而,两者在实现和使用上都有优缺点。

    我要完全概括(纯粹主义者原谅我!)但是,大致来说,编译语言的优点如下:

    • 通过直接使用目标计算机的本机代码提高性能
    • 在编译阶段应用相当强大的优化的机会

    以下是解释语言的优点:

    • 更容易实现(编写好的编译器非常困难!!)
    • 无需运行编译阶段:可以“即时”直接执行代码
    • 可以更方便地使用动态语言

    请注意,现代技术(如字节码编译)增加了一些额外的复杂性——这里所发生的是编译器针对的是一个“虚拟机”,它与底层硬件不同。然后,这些虚拟机指令可以在以后的阶段重新编译以获得本机代码(例如,Java JVM JIT编译器所做的)。

        2
  •  91
  •   lunaryorn    16 年前

    一种语言本身既不是编译的,也不是解释的,只有一种语言的特定实现。Java是一个很好的例子。有一个基于字节码的平台(JVM)、一个本地编译器(GCJ)和一个用于Java超集(BSH)的ItPiTe。那么Java是什么呢?字节码编译、本机编译或解释?

    其他被编译和解释的语言是scala、haskell或ocaml。每种语言都有一个交互式解释器,以及一个编译到字节的代码或本机代码。

    所以一般来说,用“编译的”和“解释的”对语言进行分类没有什么意义。

        3
  •  50
  •   NealB    16 年前

    从以下方面开始思考: 从过去爆炸

    很久以前,有一段时间,在计算机领域生活着 口译员和编辑。各种各样的纷争接踵而至 一个接一个。总体意见 那时 有点像:

    • 解释器:快速开发(编辑和运行)。执行速度慢,因为每个语句都必须解释为 每次执行机器代码时(想想这对执行了数千次的循环意味着什么)。
    • 编译器:开发缓慢(编辑、编译、链接和运行)。编译/链接步骤可能需要很长时间)。快的 执行。整个程序已经在本机代码中。

    运行时的一个或两个数量级差异 解释程序和编译程序之间存在性能。其他区别 例如,代码在运行时的可变性也引起了一些兴趣,但主要的 区别在于运行时性能问题。

    今天,景观的发展到了这样一个程度,编译/解释的区别是 相当不相关。许多 编译语言调用的运行时服务不是 完全基于机器代码。而且,大多数解释语言都被“编译”成字节码。 执行前。字节码解释器非常有效,可以与某些编译器生成的解释器相媲美。 从执行速度的角度来看代码。

    典型的区别是编译器生成本机代码,解释器读取源代码和 使用某种运行时系统动态生成机器代码。 如今,几乎所有的经典口译员都已不复存在。 编译成字节码(或其他半编译状态),然后在虚拟“机器”上运行。

        4
  •  23
  •   Carl Smotricz    16 年前

    极端和简单的情况:

    • 编译器将以目标计算机的本机可执行格式生成二进制可执行文件。这个二进制文件包含除系统库之外的所有必需资源;它可以在没有进一步准备和处理的情况下运行,并且运行起来像闪电一样,因为代码是目标计算机上CPU的本机代码。

    • 解释器将在一个循环中向用户提供一个提示,用户可以在该循环中输入语句或代码,并在点击时 RUN 或者等效的解释器将检查、扫描、分析并解释性地执行每一行,直到程序运行到停止点或错误为止。因为每一行都是单独处理的,而且口译员没有从以前看到过的行中“学习”任何东西,所以每一行每次都要努力将人类可读的语言转换为机器指令,所以速度很慢。从好的方面来说,用户可以通过各种方式检查和交互程序:更改变量、更改代码、在跟踪或调试模式下运行…无论什么。

    有了这些障碍,让我来解释一下,生活不再那么简单了。例如,

    • 许多口译员将预先编译他们所给的代码,这样翻译步骤就不必反复进行。
    • 有些编译器编译的不是CPU特定的机器指令,而是字节码,一种虚拟机器的人工机器代码。这使得编译后的程序更易于移植,但在每个目标系统上都需要一个字节码解释器。
    • 字节码解释器(我在这里看Java)最近倾向于重新编译它们在执行之前被获取给目标部分的CPU的字节码(称为JIT)。为了节省时间,通常只对经常运行的代码(热点)执行此操作。
    • 一些看起来和行为类似于解释器的系统(例如clojure)会立即编译所获得的任何代码,但允许交互式访问程序的环境。这基本上就是译员使用二进制编译速度的便利性。
    • 有些编译器并不真正编译,它们只是预消化和压缩代码。我听说过Perl就是这样工作的。所以有时候编译器只是做了一点工作,而大部分工作仍然是解释。

    最后,这些天,解释与编译是一种权衡,编译花费的时间(一次)通常会得到更好的运行时性能,但解释环境会给交互提供更多的机会。编译和解释主要是关于如何在不同的过程中“理解”程序的工作,而随着语言和产品试图提供最好的两个世界,这条线现在有点模糊。

        5
  •  19
  •   Bhavin Shah    11 年前

    http://www.quora.com/What-is-the-difference-between-compiled-and-interpreted-programming-languages

    没有区别,因为__编译的编程语言__和 _解释的编程语言_不是有意义的概念。任何 编程语言,我真正的意思是任何,可以被解释或 编译。因此,解释和汇编是执行 技术,而不是语言的属性。

    解释是另一个程序 解释程序,代表正在执行的程序执行操作 为了运行它而解释。如果你能想象读一个程序 一步一步地做它所说的事情,在一块划痕上说 纸,那就是解释程序也能做的。共同的理由 解释一个程序是口译员相对容易 写。另一个原因是解释程序可以监视 程序在运行时尝试执行策略,例如 安全性。

    编译是一种用一种语言编写程序的技术。 (_源语言_)被翻译成另一个程序 语言(目标语言),希望意思相同 作为原始程序。在进行翻译时,通常 编译器还尝试以 使对象程序更快(不改变其含义!)A 编译程序的常见原因是 以对象语言快速运行程序,无需开销 一路解读源语言。

    根据上面的定义,您可能已经猜到这两个 实现技术不是相互排斥的,甚至可能是 互补的。传统上,编译器的目标语言是 机器代码或类似的东西,指 由特定的计算机CPU理解的程序设计语言。这个 然后机器代码会在金属上运行(尽管人们可能会看到,如果 一个看起来足够近,金属的工作原理非常像 解释器)。然而,今天,使用编译器 生成要解释的对象代码,例如, Java是如何使用的(有时仍然如此)。有 将其他语言转换为javascript的编译器,即 通常在Web浏览器中运行,该浏览器可能解释javascript,或者 用虚拟机或本机代码编译它。我们还有口译员 对于机器代码,它可以用来模拟一种硬件 另一个。或者,可以使用编译器生成对象代码,即 然后是另一个编译器的源代码,它甚至可以编译 在内存中编写代码,以便它及时运行,然后运行。…你得到 这个想法。有很多方法可以将这些概念结合起来。

        6
  •  11
  •   Niko Bellic    12 年前

    解释源代码相对于编译源代码的最大优势是 便携性 .

    如果编译了源代码,则需要为要运行程序的每种类型的处理器和/或平台(例如,一种用于Windows x86,一种用于Windows x64,一种用于Linux x64,等等)编译不同的可执行文件。此外,除非您的代码完全符合标准,并且不使用任何平台特定的功能/库,否则您实际上需要编写和维护多个代码基!

    如果您的源代码被解释了,您只需要编写一次,并且它可以被任何平台上合适的解释程序解释和执行!它是 便携式的 !请注意,解释器本身是一个可执行程序, 为特定平台编写和编译。

    编译代码的一个优点是 隐藏源代码 来自最终用户(可能是 知识产权 )因为您没有部署原始的人类可读的源代码,而是部署了一个模糊的二进制可执行文件。

        7
  •  7
  •   Michael Borgwardt    16 年前

    一个编译器和一个解释器做同样的工作:把一种编程语言翻译成另一种pgoraming语言,通常更接近硬件,通常是直接的可执行机器代码。

    传统上,“编译”意味着这种转换一次完成,由开发人员完成,生成的可执行文件分发给用户。纯示例:C++。 编译通常需要相当长的时间,并尝试执行大量昂贵的optmation,以便生成的可执行文件运行得更快。最终用户没有自己编译东西的工具和知识,并且可执行文件通常必须在各种硬件上运行,因此不能进行许多特定于硬件的优化。在开发过程中,单独的编译步骤意味着更长的反馈周期。

    传统上,“解释”意味着当用户想要运行程序时,翻译会“即时”进行。纯示例:香草PHP。一个幼稚的解释器每次运行时都必须解析和翻译每一段代码,这使得它非常慢。它不能进行复杂的、代价高昂的优化,因为它们所花费的时间比执行时节省的时间要长。但它可以充分利用它运行的硬件的功能。缺少单独的编译步骤可以减少开发期间的反馈时间。

    但如今,“编译与解释”并不是一个黑白的问题,两者之间存在着阴影。天真、简单的口译员几乎灭绝了。许多语言都使用两步流程,将高级代码转换为独立于平台的字节码(这样更容易解释)。然后,您有“实时编译器”,每个程序运行最多编译一次代码,有时缓存结果,甚至智能地决定解释很少运行的代码,并对运行很多的代码进行强大的优化。在开发过程中,调试程序能够在运行的程序中切换代码,即使对于传统的编译语言也是如此。

        8
  •  4
  •   Uri    16 年前

    首先,一个澄清,Java不是完全静态编译和链接的方式C++。它被编译成字节码,然后由JVM解释。JVM可以对本机语言进行及时编译,但不必这样做。

    更重要的是:我认为互动性是主要的实际区别。由于所有内容都被解释了,所以您可以从代码中摘录一小部分,然后根据环境的当前状态进行分析和运行。因此,如果您已经执行了初始化变量的代码,那么您就可以访问该变量等。它确实为函数样式这样的事情提供了自己的途径。

    然而,口译成本很高,尤其是当你有一个包含大量参考资料和上下文的大型系统时。根据定义,这是浪费的,因为相同的代码可能需要解释和优化两次(尽管大多数运行时对此都有一些缓存和优化)。不过,您需要支付运行时成本,并且经常需要运行时环境。您也不太可能看到复杂的过程间优化,因为目前它们的性能没有充分的交互作用。

    因此,对于不会发生太大变化的大型系统,对于某些语言,预编译和预链接所有内容更有意义,可以执行所有可以执行的优化。最后是一个非常精简的运行时,它已经针对目标机器进行了优化。

    至于生成可执行文件,这与它无关,imho。通常可以从编译语言创建可执行文件。但也可以从解释语言创建可执行文件,除非解释器和运行时已经打包在可执行文件中,并且对您隐藏。这意味着您通常仍然要支付运行时成本(尽管我确信对于某些语言,有一些方法可以将所有内容转换为树可执行文件)。

    我不同意所有的语言都可以交互。某些语言,如C,与机器和整个链接结构联系在一起,我不确定您是否可以构建一个有意义的、完全成熟的交互版本。

        9
  •  2
  •   Steven Mohr    16 年前

    很难给出一个实际的答案,因为不同之处在于语言定义本身。可以为每种编译语言构建解释程序,但不可能为每种解释语言构建编译器。这与语言的正式定义有关。所以,理论信息学的东西在大学里是不受欢迎的。

        10
  •  2
  •   pacholik    9 年前

    python book_©2015 Imagine Publishing Ltd,只是通过第10页中提到的以下提示来消除差异,如下所示:

    诸如python之类的解释语言是将源代码转换为机器代码,然后在程序每次运行时执行的语言。这与编译语言(如C)不同,其中源代码仅在每次程序运行时转换为机器代码,然后执行生成的机器代码。

        11
  •  1
  •   salehvm    9 年前

    编译是从用编译的编程语言编写的代码创建可执行程序的过程。编译允许计算机运行和理解程序,而不需要创建程序所用的编程软件。当一个程序被编译时,它通常是为一个特定的平台(如IBM平台)编译的,该平台与IBM兼容的计算机一起工作,而不是其他平台(如苹果平台)。 第一个编译器是由GraceHopper在哈佛MarkI计算机上开发的。今天,大多数高级语言都将包含自己的编译器,或者提供可用于编译程序的工具包。使用Java的编译器的一个很好的例子是Eclipse,一个用C和C++使用的编译器的例子是GCC命令。根据程序的大小,编译需要几秒钟或几分钟,如果编译时没有遇到错误,则会创建一个可执行文件。请检查此信息。