你知道「編譯」與「解釋」的區別嗎?

最近在看一些編譯過程的知識點,看的比較多的是英文文獻。
在這之間常常遇到的兩個單詞讓我着實迷惑:Compiler, Interpreter
中文翻譯分別是:編譯器,解釋器。java

若是有人問咱們「你知道什麼是編譯器麼?」,
咱們頗有可能首先蔑視一下這我的,而後說:「知道啊,不就編譯編程語言的程序嘛!」
要是別人再追問一句「那你知道解釋器麼?」,
這時候頗有可能也會說「知道啊。」,可是很難再帶有蔑視的語氣了。
要是再問一句「那麼編譯器和解釋器的區別是什麼啊?」,
「呃......」程序員

那麼到底什麼是「編譯器」,什麼是「解釋器」?
雖然對於兩個詞,咱們很「耳熟」,可是「能詳」麼?
彷佛咱們並無認真對待這兩個詞彙。編程

什麼是編譯器

摘自 Wiki Compiler 一段緩存

A compiler is a computer program (or a set of programs) that transforms source code written in a programming language (the source language) into another computer language (the target language), with the latter often having a binary form known as object code. The most common reason for converting source code is to create an executable program.編程語言

大概意思:工具

編譯器是一種計算機程序,負責把一種編程語言編寫的源碼轉換成另一種計算機代碼,後者每每是以二進制的形式被稱爲目標代碼(object code)。這個轉換的過程一般的目的是生成可執行的程序。性能

編譯器的產出是「另一種代碼」,而後這些代碼等着被別人拿來執行,若是還不能直接被執行,那麼還須要再編譯或解釋一遍,再交由計算機硬件執行。
編譯器,每每是在「執行」以前完成,產出是一種可執行或須要再編譯或者解釋的「代碼」。this

什麼是解釋器

摘自 Wiki Interpreter 一段操作系統

In computer science, an interpreter is a computer program that directly executes, i.e. performs, instructions written in a programming or scripting language, without previously compiling them into a machine language program. An interpreter generally uses one of the following strategies for program execution:翻譯

  1. parse the source code and perform its behavior directly.
  2. translate source code into some efficient intermediate representation and immediately execute this.
  3. explicitly execute stored precompiled code made by a compiler which is part of the interpreter system.

大概意思:

在計算機科學中,解釋器是一種計算機程序,它直接執行由編程語言或腳本語言編寫的代碼,並不會把源代碼預編譯成機器碼。一個解釋器,一般會用如下的姿式來執行程序代碼:

  1. 分析源代碼,而且直接執行。
  2. 把源代碼翻譯成相對更加高效率的中間碼,而後當即執行它。
  3. 執行由解釋器內部的編譯器預編譯後保存的代碼

能夠把解釋器當作一個黑盒子,咱們輸入源碼,它就會實時返回結果。
不一樣類型的解釋器,黑盒子裏面的構造不同,有些還會集成編譯器,緩存編譯結果,用來提升執行效率(例如 Chrome V8 也是這麼作的)。
解釋器一般是工做在「運行時」,而且對於咱們輸入的源碼,是一行一行的解釋而後執行,而後返回結果。

分兩個維度比較一下

表現 Behavior

  • 編譯器把源代碼轉換成其餘的更低級的代碼(例如二進制碼、機器碼),可是不會執行它。
  • 解釋器會讀取源代碼,而且直接生成指令讓計算機硬件執行,不會輸出另一種代碼。

性能 Performance

  • 編譯器會事先用比較多的時間把整個程序的源代碼編譯成另一種代碼,後者每每較前者更加接近機器碼,因此執行的效率會更加高。時間是消耗在預編譯的過程當中。
  • 解釋器會一行一行的讀取源代碼,解釋,而後當即執行。這中間每每使用相對簡單的詞法分析、語法分析,壓縮解釋的時間,最後生成機器碼,交由硬件執行。解釋器適合比較低級的語言。可是相對於預編譯好的代碼,效率每每會更低。如何減小解釋的次數和複雜性,是提升解釋器效率的難題。

關於代碼,須要知道的幾個概念

在看了很多很少關於「編譯和解釋」的文章以後,我發現下面的詞彙是大量出現的。
知道這些詞彙表明的意思,以及對應的層次,可以更好地看懂別人所要表達的意思。

高級語言代碼 High-Level Code

高級語言代碼,天然是指由高級編程語言編寫代碼,對計算機的細節有更高層次的抽象。
相對於低級編程語言(low-level programming language)更接近天然語言(人類的語言)。
集成一系列的自動工具(垃圾回收,內存管理等),會讓程序員延長壽命,更快樂的編寫出更簡潔,更易讀的程序代碼。

低級語言代碼 Low-Level Code

低級語言代碼,指由低級編程語言編寫的代碼,相對高級語言,少了更多的抽象概念,更加接近於彙編或者機器指令。
可是這也意味着代碼的可移植性不好。

在我看來,高與低,只是一組相對詞而已。
越高級的語言,性能、自由度越不及低級語言。
可是在抽象、可讀可寫性、可移植性越比低級語言優秀。
在之前的年代,C/C++語言相對彙編語言,機器指令來講,確定是高級語言。
而到了今天,咱們更多人對C語言偏向認知爲「低級語言」。
或許將來世界的開發者,看咱們如今所熟悉的Java、PHP、Python、ECMAScript等等,都是「low」到爆的語言。

彙編語言 Assembly Language

彙編語言做爲一門低級語言,對應於計算機或者其餘可編程的硬件。
它和計算機的體系結構以及機器指令是強關聯的。
換句話說,就是不一樣的彙編語言代碼對應特定的硬件,因此不用談可移植性了。
相對於須要編譯和解釋的高級語言代碼來講,彙編代碼只須要翻譯成機器碼就能夠執行了。
因此彙編語言也每每被稱做象徵性機器碼(symbolic machine code)

字節碼 Byte Code

字節碼嚴格來講不算是編程語言,而是高級編程語言爲了種種需求(可移植性、可傳輸性、預編譯等)而產生的中間碼(Intermediate Code)。
它是由一堆指令集組成的代碼,例如在javac編譯事後的java源碼產生的就是字節碼。
源碼在編譯的過程當中,是須要進行「詞法分析 → 語法分析 → 生成目標代碼」等過程的,在預編譯的過程當中,就完成這部分工做,生成字節碼。
而後在後面交由解釋器(這裏一般指編程語言的虛擬機)解釋執行,省去前面預編譯的開銷。

機器碼 Machine Code

機器碼是一組能夠直接被CPU執行的指令集,
每一條指令都表明一個特定的任務,或者是加載,或者是跳轉,亦或是計算操做等等。
全部能夠直接被CPU執行的程序,都是由這麼一系列的指令組成的。
機器碼但是看做是編譯過程當中,最低級的代碼,因外再往下就是交由硬件來執行了。
固然機器碼也是能夠被編輯的,可是以人類難以看懂的姿式存在,可讀性很是差。

從熟悉的編程語言的角度來看看

從熟悉的編程語言的角度來看

從左往右看,

  1. 以 Java 爲例,咱們在文本編譯器寫好了 Java 代碼,交由「編譯器」編譯成 Java Bytecode。而後 Bytecode 交由 JVM 來執行,這時候 JVM 充當了「解釋器」的角色,在解釋 Bytecode 成 Machine Code 的同時執行它,返回結果。
  2. BASIC 語言(早期的能夠由計算機直譯的語言) 爲例,經過文本編譯器編寫好,不用經歷「編譯」的過程,就能夠直接交由操做系統內部來進行「解釋」而後執行。
  3. 以 C 語言爲例,咱們在文本編譯器編寫好源代碼,而後運行 gcc hello.c 編譯出 hello.out 文件,該文件由一系列的機器指令組成的機器碼,能夠直接交由硬件來執行。

抽象看本質:人與計算機之間的鴻溝

不管是最近在看《暗時間》的做者劉未鵬,仍是前一段時間聽《以產品思惟寫文章》講座的阿禪,仍是其餘的不少聰明的人。
他們都強調「抽象看本質」的能力,能從事物自己抽象出共通屬性,看待本質。
這也是不少人所說的「跳出這個框框再看」的思惟方式。

不管是「編譯 Compile」仍是「解釋 Interpret」。
本質仍是「人與計算機的交流形式」,人的語言最終轉換成機器語言。
一句 「Hello World」,通過一些列的「編譯」和「解釋」,最終轉換成一系列包含機器指令的那些0和1,機器傻傻執行完以後,告訴你結果。

就這麼一個過程,咱們就須要不少的翻譯官。
有些翻譯官能夠作到同聲傳譯(解釋),有些翻譯官卻只能把咱們的意圖記下來再所有翻譯(編譯)給計算機。
而每每一個翻譯官能力有限,也只能把你的語言,翻譯成另一種低級點的語言,再由另外懂這個語言的翻譯官來翻譯更接近計算機能讀得懂的語言。

人類和計算機的鴻溝.png

一句話描述「編譯」與「解釋」?

不如這張圖來得直接:

一句話描述編譯與解釋

編譯 Compile:把整個程序源代碼翻譯成另一種代碼,而後等待被執行,發生在運行以前,產物是「另外一份代碼」。
解釋 Interpret:把程序源代碼一行一行的讀懂而後執行,發生在運行時,產物是「運行結果」。

參考

stackoverflow.com/questions/2…
www.wikiwand.com/en/Interpre…)
www.wikiwand.com/en/Compiler
www.wikiwand.com/en/Machine_…
www.wikiwand.com/en/High-lev…
www.wikiwand.com/en/Low-leve…
www.wikiwand.com/en/Bytecode

關於轉載

本文默認容許轉載,但:

  1. 請務必註明出處:BlueSun | 《你知道「編譯」與「解釋」的區別嗎?」》
  2. 若是你不介意,我但願轉載的同時,能夠獲得一聲告知。(Email:huangjerryc@gmail.com)

感謝!

相關文章
相關標籤/搜索