fbpx

編譯與直譯程式語言指南

本文由 Zenva 提供。 Zenva 為澳洲遊戲程式設計線上學習平台

無論您是想提升您的計算機科學技能還是深入研究一種新的程式語言,您都可能會想到一個問題:編譯語言還是直譯語言。 雖然這些術語被廣泛使用,但兩者之間的區別並不總是一目瞭然——也不是當你開始寫程式時就認知這很重要。

在本文中,我們將揭開編譯語言與直譯語言的神秘面紗,並幫助您從頭開始理解這些重要的技術概念,希望這些概念能更好地幫助您選擇正確的程式設計路徑。

計算機如何工作

了解編譯型和直譯型編程語言差異的第一步是對計算機的工作方式有一個基本的了解。

機器碼和二進制碼

本質上,計算機只是一堆電信號。有時我們關閉這些信號,有時我們打開它們。在某種程度上,您可以將其視為更基本的莫爾斯電碼( morse code )版本。而且,就像摩爾斯電碼一樣,我們可以給這些電信號值。

在這個概念開始時,我們決定分配簡單的 0 和 1 值來指示信號是設置為關閉還是打開。然後,我們將這些 0 和 1 組合成序列,並賦予每個序列含義。對於大多數人來說,你知道這個解決方案是二進制的,而二進制代碼是機器代碼背後的主要驅動力,它使計算機實際上在最基本的層面上工作。

不過,此時您可能會問,為什麼要設計這樣的計算機?好吧,本質上,為了讓計算機盡可能快地工作,我們需要盡可能簡單的數值來提供給 CPU。如果沒有這個,計算機的運行速度可能永遠與您試圖從偏遠島嶼訪問的撥號網際網路一樣慢。因此,這個乾淨的解決方案為我們提供了在計算機上執行所有操作所需的速度。

什麼是程式語言?

綜上所述,您可能知道我們通常不使用二進制編碼。當然,如果您願意的話,您絕對可以使用二進制(或易於轉換為二進制的十六進制數字)進行編碼。但是,要知道這將是一個巨大的挑戰!

相反,人們找到了一種更簡單的方法來解決這個問題:程式語言。

程式語言與外語非常相似。它們為我們提供了一種用詞彙和“語法”(即句法)進行交流的結構化方式——在這種情況下,是關於如何執行某項任務的說明。與 0 和 1 不同,程式語言是為人類而設計的,因此我們可以輕鬆地用它們進行讀寫,以實現我們想要的功能。現在,這裡需要一些細微差別,因為我們仍然需要以與計算機相容的方式(即機器指令)來傳達該功能。但是寫一個循環比寫一萬個字符的二進制來達到同樣的效果要容易得多。

但是,正如您可能已經猜到的那樣,我們不能將這種人類可讀的語言完全提供給只真正理解二進制的計算機。因此,我們需要某種方法將程式語言所說的內容翻譯成計算機可以讀取的二進制格式。也許我們有辦法編譯這個翻譯,或者甚至可以當場解釋它?

因此,我們來到了本文的主題:編譯語言與直譯語言。

編輯程式語言到機器碼

簡而言之,現在讓我們概述一下什麼是編譯語言,什麼是直譯語言。深入研究時請記住,許多語言都可以使用這兩種編譯方法(例如:Python)。然而,一般來說,大多數語言都有一個偽默認方法,這就是為什麼將語言分為這些類別是有用的。我們還將在這裡介紹第三類,涉及將代碼翻譯成機器語言,它與兩個主要語言交織在一起:即時編譯。

什麼是編譯語言?

編譯型程式語言是一種在執行之前使用編譯器將程式翻譯成機器代碼的語言。一旦程式完成編碼,編譯語言就會經歷通常稱為“建構( build )”的步驟。這個構建步驟基本上指示編譯器——它有關於如何翻譯程式語言的指令——進行翻譯工作,並基本上創建一個新的二進制檔。然後,當你執行程式時,計算機直接進入這個二進制檔,並根據那些已經準備好讓計算機理解的編譯指令執行程式。

流行編譯語言示例C++、C#、F#、Go、Kotlin、Python(也可以直譯)、Rust、Swift

什麼是直譯語言?

直譯型程式語言是一種在執行時使用直譯器將程式翻譯成機器代碼的語言。 與需要額外“建構”步驟才能工作的編譯語言不同,直譯器或多或少是實時翻譯的。 因此,從您開始執行程式的那一刻起,直譯器就會立即開始逐行翻譯內容,而無需為此創建額外的檔案。 可以將其視為大型演講中的人工翻譯,他們會在現場為聽障用戶聆聽並翻譯成手語。

流行的解釋語言示例JavaScript、Lua、Perl、PHP、Python(也可以編譯)、Ruby、PowerShell

什麼是即時編譯器?

雖然我們還沒有提到它,但有一種編譯類型與編譯語言和直譯語言高度相關並且值得一提:即時編譯器。 即時編譯器背後的想法是捕捉編譯器和直譯器的好處(我們將在下面詳細討論)。 這些類型的編譯器在執行期間分析程式碼並獲取最關鍵的部分並將它們預翻譯成機器代碼。 雖然在分析過程中執行速度會變慢(這種情況經常發生),但總體而言,您可以繞過常規解釋語言的一些問題——主要是它們通常速度較慢的部分。

可以使用即時編譯器的語言示例:Java、C#、Scala、Visual Basic

編譯與直譯:優點和缺點

因此,我們在最基本的層面上了解編譯與直譯的含義。但是,為什麼要選擇一種語言/編譯方法而不是另一種。在本節中,我們將概述編譯語言和直譯語言之間的主要優缺點。

執行速度

大多數情況下,在討論編譯和直譯語言時,這可能是您考慮的要點。這是有充分理由的,因為這通常是許多各別開發者的主要決定因素。

如上所述,編譯語言在執行之前翻譯代碼,而解釋語言在運行時進行。您可以將其視為在上課前一天晚上做作業的學生,而不是在每個人都將論文交給老師時做作業的學生。

由於前一天晚上做這件事的學生已經做好了準備,所以交作業的整個過程要快得多——編譯語言也是如此。計算機已經建構了機器代碼,因此它只需要查看正確的檔案即可讀取。這使得程式運行速度更快,因為沒有額外的跑腿工作要做。這也是為什麼許多需要超快運行時的遊戲使用 C++ 等編譯語言來完成工作的原因。

與此同時,試圖在課堂上完成作業的學生會慢慢溜到隊伍的後面,而不是馬上交作業。直譯語言就像這樣。因此,從本質上講,它們確實運行慢些,只是因為它們是實時翻譯的,所以它們執行程式的速度沒有那麼快。現在,請記住,對於小程式,我們談論的是毫秒級的問題,這對普通人來說並不重要。但是,對於較大的程式,尤其是那些擁有龐大資料庫的程式,速度對於盡快完成是不可或缺的。

編譯步驟

在編譯與解釋的討論中還有另一個“偽速度”差異,這超出了執行範圍:編譯步驟。我們的意思是,我們可以多快地從原始程式碼到計算機需要盡可能快地執行它的任何內容。

在這方面,直譯型語言實際上具有優勢。由於直譯性語言是在運行時翻譯的,因此作為開發人員,您無需採取任何實際的額外步驟來從程式碼到執行。通常,您需要做的就是觸發執行,然後爆發,您的程式碼正在運行並按命令執行。

不過,如前所述,編譯語言確實需要額外的“建構”步驟才能從程式碼轉換為可執行應用程式。這個建構步驟需要多長時間因程式而異,很大程度上取決於複雜性。例如,您的簡單 “Hello World” 腳本可能需要不到 1 秒的時間來編譯。另一方面,擁有 100 多個角色和腳本的開放世界遊戲可能最多需要幾分鐘。

您可以將這兩種“速度”視為一對權衡取捨。編譯語言犧牲編譯“速度”以獲得更快的執行速度,直譯語言犧牲執行速度以獲得更快的編譯速度。

修改靈活性

對於編譯型和直譯型語言,這一點與關於編譯的最後一點密切相關。當我們談論修改靈活性時,我們談論的是程式設計師編輯他們的程式碼然後重新運行它有多容易。討論這一點非常重要,因為無論您的技能水準如何,您都很可能需大量重寫程式碼。

再次與上述類似,直譯語言在這裡贏得了優勢。因為翻譯是在運行時進行的,沒有真正的編譯時間;您可以隨時編輯程式碼並立即返回執行。事實上,您甚至可以在程式運行時編輯程式碼,而不會受到任何真正的不良影響!確實就是這麼簡單。

使用編譯語言,無論何時更改程式碼,即使只是添加缺少的分號,都必須重新編譯程式。由於此編譯可能需要一些時間,因此您可以想像這很快就會累加起來,並使修改始終不是最快或最靈活的任務。因此,在再次編譯程式之前,您確實需要更加注意,不能只是即時編輯。

編譯錯誤處理

另一個與編譯語言和直譯語言的編譯有關的問題是有關錯誤的處理。換句話說,當您的編譯方法在程式碼中遇到編譯錯誤時會做什麼?這個更難說誰有優勢或劣勢,因為這取決於你什麼時候想抓到這些錯誤。

如果存在會影響編譯的編碼錯誤,編譯語言將不允許你編譯東西。通常,大多數編譯器只是停止翻譯過程並通知您編譯過程失敗的原因。一方面,這使得您不會執行無論如何都會遭受嚴重錯誤的程式。因此,這使您可以在問題成為問題之前解決問題。但是,這會使 debug 程式變得更加困難,因為如果不修復某些錯誤,您將無法測試執行—— 有些錯誤你如果不執行就很難找到。

直譯性語言將允許您運行有錯誤的程式,並在這些錯誤發生時簡單地記錄。因此,它具有讓您在運行時進行所有 debug 的優勢,並且您的程式將繼續嘗試並在這種情況下盡其所能運行。話雖如此,這也意味著在程式遇到這些編譯錯誤之前,您不會知道這些編譯錯誤。這對於一個小程式來說可能很好,但是如果你有 1000 行並且很少調用一個函數,那麼在程式運行之前你甚至可能永遠不會看到這個錯誤出現。

因此,總而言之,這取決於您作為開發人員想要什麼!

可移植性

最後一個要討論的編譯和直譯語言的主要優點/缺點是關於可移植性。在這方面,我們談論的是在設備之間使用程式是多麼容易。

這是編譯語言處於劣勢的部分。到目前為止,我們在這篇文章中沒有提到的一件事是,當將事物編譯為機器代碼時,編譯器會針對特定的目標平台/CPU 這樣做。因此,您不能只取一個要在手機上運行的檔案,將其彈出到計算機中,然後讓計算機毫無問題地執行相同的編譯二進制檔。每個平台都需要自己獨特的編譯方法才能工作。所以,如果你想讓你的程式在多台機器上工作,你必須為每個目標平台編譯一個單獨的檔——這顯然需要時間。

直譯語言沒有這個缺點。由於事物是在運行時翻譯的,因此它們非常獨立於平台,並且實際上不需要任何額外的相容性步驟。這是網際網路上大量使用 JavaScript 等語言的一個重要原因。由於這是一種直譯型語言,因此無論您如何訪問 JavaScript 程式,它都是跨平台相容的。其他直譯語言也有同樣的體驗,所以對於終極的跨平台能力,這是一個需要考慮的方向。

為什麼編譯與直譯很重要

在結束這篇文章之前,我們想花一點時間討論”編譯”之於”直譯”空間的最後一部分:為什麼這很重要。

不同的程式需要不同的執行速度

我們在上面談到了一點,但這一點值得重申。不管你怎麼看,編譯語言執行得更快,即使編譯過程需要更長的時間。而且,根據您要編寫程式的內容,這可能會產生巨大的影響。

例如,請注意僅限瀏覽器的遊戲與諸如 Soulcalibur VI 之類的 AAA 遊戲之間的差異。大多數基於瀏覽器的遊戲都是用 JavaScript(一種直譯性語言)製作的,因此範圍更小。這主要是因為直譯語言在某種程度上限制了這些遊戲的運行速度。因此,為了讓它們保持無延遲,開發人員必須使它們更小——無論是圖形還是編程。

然而,有了 Soulcalibur VI,有更多的空間來處理複雜的圖形和機制。由於該遊戲基於 C++(一種編譯語言),因此該遊戲能夠利用速度優勢提供更全面的 3D 圖形體驗——這是瀏覽器遊戲無法做到的。

不過,總而言之,這對您意味著您需要選擇一種適合您專案的語言。如果您想用 3D 圖形建構一個巨大的開放世界 MMORPG,你不會真的想要直譯語言,因為你需要速度。另一方面,如果您只是製作一個簡單的問答遊戲,而速度不是一個因素,那麼直譯性語言就可以了,在某些情況下甚至可能會更好。因此,這種區別對於正確確定專案範圍非常重要。

程式碼編輯可能需要更快或更容易

當您開始深入研究機器學習等更高級的概念時,作為開發人員,您最不想做的事情就是用編譯器時間阻塞前端。不幸的是,這就是編譯語言會做的事情,即使編譯你的專案需要不到 1 秒的時間。有時,您確實需要能夠快速測試某些功能、程式碼行等才能完成它。有時您可能需要進行實時測試以確保正確處理某些數據。

如果您覺得您正在處理需要更輕鬆地即時編輯的內容,那麼直譯型語言可能是一個更好的選擇——以及為什麼知道其中的差異很重要。這樣做,您可以選擇一種可以立即執行的語言,並確保您嘗試製作的任何複雜程式都能按預期工作。

但總的來說,您需要了解這兩種編譯類型之間的區別,以便為您的專案做出一個好的選擇。

跨平台注意事項

這種差異很重要的另一個原因是我們上面解釋的可移植性因素。如果您需要可以從其他設備輕鬆訪問的東西,那麼您可能想要使用直譯程式碼。這樣您就不必擔心某些與編譯器相關的因素,並且可以專注於您的專案。如果您正在製作諸如網路應用程式之類的東西,則可能尤其如此,您需要確保手機和 PC 可以開箱即用地輕鬆使用它,並且您不會因多個執行檔而使您的網站陷入困境。

無論哪種方式,歸根結底,使用解釋語言使跨平台程式在多個設備上運行要比使用編譯語言容易得多。話雖如此,大多數編譯語言也可以很容易地跨平台,因為像 Unity Unreal Engine(僅作為示例)這樣的程式帶有簡單的一鍵式解決方案,讓您建構專案而不必大驚小怪。唯一需要考慮的是,它需要更多時間,因為您必須為每個設備進行單獨的建構。

儘管如此,了解差異有助於您對哪種語言最適合您的專案做出另一個明智的決定。

結語

理解編譯語言與直譯語言的區別絕對很重要。 它不僅會首先影響您為專案選擇的語言,還會影響您在實際程式設計部分中如何處理專案。 此外,了解差異可以讓您在計算機科學領域獲得巨大優勢,因為這些關鍵概念將幫助您深入了解計算機如何工作的其他方面。 話雖如此,請記住編譯語言和直譯語言都只是幫助您實現特定目標的工具。

在我們結束之前,我們確實想在下面為您提供更多資源,以幫助您進一步深入學習程式語言並選擇適合您的語言。 不過,無論您的選擇如何,我們都希望您能夠更好地編寫您的夢想專案!

這個網站採用 Akismet 服務減少垃圾留言。進一步了解 Akismet 如何處理網站訪客的留言資料

Powered by WordPress.com.

Up ↑

%d 位部落客按了讚: