第五章、電腦世界裡的翻譯年糕(高階程式語言概論)

事情發生在寒假開始的第一天的上午。

伴隨著『碰!』的一響,只有桐仁在的電腦研究社和文藝社共用的社團辦公室的門被粗暴地推開,他開始有一種似乎不太妙的預感。

只見一位有著亞麻色長髮的女孩,相當有朝氣地高舉著右手向坐在鐵椅上敲著鍵盤的桐仁打招呼,同時像是連珠砲似地說道:「唷呵~學長,我又來了~~告訴學長一個好消息!小深夏這次計概的補考拿了九十幾分再加上已經公佈的其他科的程績已經確定不會被二一了所以接下來就繼續麻煩學長了喲!我絕對,絕對不會讓小深夏逃……」

而且她的左手還拖著一個身著淡綠色連身洋裝,怎麼看身高都不到一百五十公分,臉上明顯掛著像是小動物受到驚嚇時一樣的神情,眼神也已經開始逐漸散渙的嬌小女生。

「先等一下,音羽同學!」桐仁忍不住站起身來,按住自己的太陽穴,對著滔滔不絕的音羽制止她繼續說下去。

「咦?!怎麼了嗎?學長有什麼問題嗎?」音羽露出感到困惑的表情,直盯著桐仁瞧。

「什麼有什麼問題,妳還是先放開深夏同學吧。」

深夏這才意識到原來自己的左手還拎著另一個人,而終於逃離音羽的魔爪(?)的深夏,以常人難以理解的速度和移動方式,一溜煙地躲到桐仁的身後,同時還伸著一隻小手緊抓著桐仁的衣角不放。

喂喂喂,我和妳是才第二次見面而已耶,對陌生的男人反而那麼無防備是怎麼回事啊……桐仁忍不住在心中吐嘈道。

「再說,你剛剛說的繼續麻煩我是什麼意思?深夏同學她計概的補考不是及格了嗎?那應該沒什麼問題了才對啊。」

「不……問題可大了!因為轉系要等下學期結束之後才能申請,所以我絕對不允許小深夏在下學期被二一!」

「……」

「而且以現在的狀況來看,小深夏的下學期也會很危險,所以請學長繼續幫小深夏補習。不,乾脆請學長把小深夏從文學少女改造成程式少女,讓她永遠和我在一起好了!」音羽「啪」地一聲合起雙掌,稍微彎下腰來,做出拜托的姿勢說道,還眨了眨右眼做出讓桐仁覺得根本已經幾近於犯規的可愛表情。

桐仁決定裝做沒聽到音羽剛剛說的話裡,聽起來似乎有點危險的部份,轉頭向深還緊抓著自己不放的深夏問道:「那深夏同學呢?有想要補習嗎?這種事還是要由自己決定比較好唄。」

「我……」

原本一直在旁默默不語的深夏,輕輕地點了點頭,緩慢但堅定地小聲說道:「我不想被二一。」

「好,那就這麼決定了!事不宜遲,我們馬上來開始補習吧!」音羽從桌旁拉出一張椅子坐下,並且開心地說道。

「不過話說回來……雖然說是補習,不過深夏同學的目前的進度到哪呢?如果不知道深夏同學的程度如何的話,也很難針對有問題的部份加強吧?」

「這個可不是我在誇口,不過小深夏她啊,明明數學成績就比我還要好,但是說到程式設計那門課,她可以說是完完全全地一~~竅不通呢!而且是連作業都寫不出來的那種喔!」

「有、有什麼辦法……老師在講什麼我根本就聽不懂嘛……而且至少微積分的那些數學符號以前就看過了啊。」深夏紅著臉小聲嘟囔道。

「我記得這一學期的程式設計老師還是和以前一樣吧?那也難怪,他的教法和課程安排本來就比較硬派,對於第一次接觸的人的確是比較不容易吸收。」

「硬派?」深夏問道。

「對啊,算是倒吃甘蔗型的吧,而且他滿重視他教出的學生出去是真的有能力可以直接上第一線的。像你們這學期學的是 C 語言,下學期應該教的是 Java,都是業界經常使用的程式語言,不過就某方面來說,對初學者並不是很友善,所以每年被當而要重修的人數都還滿多的。」桐仁聳肩說道。

「噫~~是這樣嗎?那這麼說來小深夏下學期的程設該不會沒救了吧?!」

「哈哈哈,沒那麼誇張啦!也有很多人是第一學期被當,第二學期卻滿分的啦,只要開竅了,其實程式設計這門課沒那麼難的啦。對了,雖然剛剛說深夏同學寫不出作業,不過基本的程式寫作流程,像是在工作站上編譯程式這些,應該沒有問題吧?」

「學長是說寫完程式後要下 gcc hw1.c 的指令這類的東西嗎?是知道要這樣做,但不是很清楚為什麼要這樣做,而且有的時候沒反應,有的時候又會出現奇怪的英文,根本就讓人搞不懂嘛。」深夏有點不滿的說道。

「哎喲,我不是和小深夏說過很多次了,編譯就只是為了把程式碼轉成機器語言而已啊。」

「可是我不知道為什麼還要多一道手續嘛……」深夏噘著嘴說道。

「妳很固執耶!笨深夏,幹嘛想這麼多啊!」

「我大概了解了深夏同學的疑問在哪了,我想我們還是從頭開始好了。深夏同學,妳還記得上一次我們說的小人電腦的指令集嗎?」

「嗯。」深夏點了點頭應道。

「那妳還記得如果要將兩個數字相加,要怎麼做嗎?」

「呃……先用 LOAD 指令將數字讀到暫存器上,再用 ADD 指令相加……?」

「再想想看,如果是在寫數學作業,妳會怎麼表示兩個數字相加呢?」

「就直接用加號表示啊,像是 1 + 1 這樣。啊!是說老師在教 C 語言的時候好像也是這樣寫的耶。」

「沒錯,比起那些小人電腦的指令,像數學一樣的表示方法簡潔,也容易理解多了對吧?」

桐仁指了指放在桌上的筆記型電腦繼續說道:「再說之前小人電腦的指令集還是因為教學需要而簡化過的,所以只有十個,但實際上我們平常在用的電腦的指令集的裡指令卻有不下上百個,如果每次寫程式都要使用那些指令,實在是太辛苦了。所以就有其他人發明了像是這學期教的 C 語言這類比較貼近數學和英文的寫程式的方法,一般叫做『高階程式語言』,讓寫程式比較容易……但之前也說過了,電腦只懂那些指令集……」

「所以就需要把 C 語言程式碼編譯成機器語言啊。」音羽嘟著嘴插口說道。

「這麼說,編譯是指翻譯嗎?」

「嗯,概念上是差不多的。就像托爾泰的《戰爭與和平》原本是用俄文寫的,但就算我們不懂俄文,但只要有翻譯過後的版本也是可以看懂他在寫些什麼是一樣的。另外雖然老師上課的時候好像沒有特別講,不過其實對於要怎麼翻譯成機器語言的指令集這件事,也有不同的策略喲。」

「學長!我知道,直譯和編譯對吧?!」

「不同的……策略?直譯?」深夏歪著頭問道,明顯跟不太上桐仁和音羽兩人的步調。

「對,要如何將高階程式語言轉成電腦真正看得懂的機器指令,主要有兩種策略,一種是像你們這學期上的 C 語言一樣的『編譯』,一種則是稱為『直譯』,像是以前的 BASIC 語言就是使用這種方法。」

說到這兒,桐仁站起身來走到白板前,在白板上畫了一些方塊後繼續說道:

「要比喻的話,直譯比較像是現場口譯的感覺,中間的這個直譯器就像是吃了小叮噹的翻譯年糕的程式,一邊讀進程式碼,一邊翻譯成電腦能夠理解的機器語言,一步步告訴電腦要做些什麼,這就叫『直譯』……通常使用這類方式的程式語言也稱為 scripting language,不過這樣的方法也有一些缺點。」

直譯程式語言執行流程

直譯程式語言執行流程

「怎麼說呢?」

「其中一個是不一定每台電腦上面都剛好有裝那個語言的直譯器,所以如果使用者需要使用那個語言寫的程式的話,必須先安裝直譯器才行。還有就是程式每次執行的時候都要重新翻譯成機器語言一次,速度會比較慢,相較之下,有一些高階語言就採取了另一種稱做『編譯』的方法,像 C 語言就是其中一種……」

桐仁在原先的直譯程式語言流程的圖案旁邊畫上另一組圖案,繼續說道:「如果說直譯像是口譯的話,那編譯就比較像是書面翻譯了。在用編譯式的程式語言開發時,我們會先將寫好的程式碼用編譯器翻譯成為電腦可以只接看得懂的機器指令,並把它儲存下來,妳剛剛提到的 gcc 就是編譯器的一種[1]。而編譯出來的檔案因為可以直接被電腦執行,所以一般會叫他可執行檔。」

編譯式程式語言執行流程

編譯式程式語言執行流程

「這樣以後只要 copy 可執行檔給別人就可以執行啦,而且因為已經是機器語言了,所以執行起來會比較快!懂了吧,固執的小深夏,這樣不是比較方便嗎?所以就跟妳說妳想太多了嘛!就只是要翻譯成機器語言而已嘛。」

「呣……好像慢慢可以理解了……所以看起來編譯式的程式語言比較方便囉?」

「不過編譯式的程式語言也不是完全沒有缺點就是了。」

「咦?可是編譯出來的程式不是比較快,也可以直接在不同的電腦上執行嗎?」

「可以『在不同的電腦上執行』這句話有點問題喲,因為實際上電腦有很多不同的種類,不同種類的電腦的指令集[2]都不太一樣,就算是同一種電腦,執行的作業系統[3]也有可能不一樣……」

「作業系統?」

「這麼說吧,小深夏知道蘋果電腦有出筆記型電腦吧?」

「嗯……以前在百貨公司裡面有看過。」

「它的畫面還有操作方式和學校跑 Windows 的電腦不同對吧?像 Windows 這類東西就叫做作業系統,在蘋果電腦上跑的那個則叫做 Mac OS,另外像妳們上程式設計課時連線的工作站跑的是另一套叫 Linux 的作業系統,到這邊還可以嗎?」

「嗯。」

「然後啊,雖然這些作業系統都是運作在支援同一種指令集的電腦上,但因為可以看得懂的可執行檔格式都不一樣,所以原本編譯給 Windows 作業系統的可執行檔,是沒辦法在麥金塔上的 Mac OS 用的。妳可能沒注意到,不過如果你把程式設計課上用 gcc 編譯出來的程式拷貝到 Windows 上的話,因為 Windows 不認識他的格式,所以也沒辦法執行的,就算是再簡單的程式也一樣。」

「這樣說的話,要在不同的電腦上執行,就得要重新寫一次嗎?」

「那倒也不是,因為 C 語言的規格是固定的,所以我們只要重新編譯一次就行了,但相對來說如果同一隻程式,要給同時給 Windows / Mac OS / Linux 執行,就要分別編譯三次,產生三種不同格式的可執行檔……很囉唆對吧?」

見到音羽和深夏點頭,桐仁繼續說道:「也因為這個原因,妳們下個學期要學的 Java,又採用了另一種不同的策略……呃,反正下學期也會用到,我就直接一次解釋完好了。」

桐仁邊講邊將白板上原先的圖案擦去,重新畫上另一個圖案。

VM 程式語言執行流程

VM 程式語言執行流程

「像 Java 這類的程式語言,則是先將程式編譯成一種叫做 bytecode 的虛擬的機器碼,然後再透過一種叫做虛擬機器 (Virtual Machine) 的程式,來將 bytecode 翻譯成機器語言來執行。用這樣方法,就能讓編譯出來的程式,在不同的作業系統上都可以跑。」

「咦?可是這樣子不就和直譯式的程式語言差不多了嗎?都還要再另外安裝程式,而且執行的時候也要重新再翻譯一次啊。」

「好問題,概念上確實是差不多的。只是因為編譯出來的 bytecode 是一種『虛擬的機器碼』,本身就和指令集上的指令類似,所以在進行翻譯的時候比較容易一點,再加上現在的電腦運算速度比以前來說快相當多,所以現在使用這種方式執行的程式,跑起來不見得會比編譯式的程式來的慢。」

「而且現在的網路愈來愈方便,使用者安裝程式也變得很簡單,所以要額外安裝 VM 這種事情,似乎就不是那麼被在乎了,可以說兩權相害取其輕者吧。」桐仁聳肩說道。

「啊~~這些不會考的東西怎麼樣都好啦!學長快點來教小深夏寫程式吧,不然我敢保證小深夏這樣的笨蛋下學期的程式設計一定會被當掉的!」音羽站起身來,挺起胸堂說道。

「知道基礎的概念還是很重要的啊……」「我才不是笨蛋呢……」

看到音羽毫無理由的自信,兩人只能無力地趴在桌上反駁……

註解

[1]GNU Compiler Collection
[2]舉例而言,目前的 PC 與麥金塔均使用 X86 的架構和指令集,智慧型手機則多使用使用 ARM 的架構和指令集。
[3]原文為 Operating System,用來讓使用者和應用程式與硬體溝通的程式,像 Windows / Mac OS / Linux... 等都是作業系統的一種。

回響