程式設計是個非常自然而直覺的概念:程式不過就是一連串以特定語言寫成的敘述。程式無所不在,連最害怕科技的人每天也都在使用程式——行車路線、食譜、美式足球戰術、DNA,全都是程式的一種。

一段「行車路線」的程式#

一份典型的行車路線程式可能長這樣:

沿 Main Street 往東出發。持續走 Main Street,直到看見右手邊有一座教堂。如果因施工而封路,就在 15th Street 右轉、Pine Street 左轉、再於 16th Street 右轉;否則直接繼續走並在 16th Street 右轉。沿 16th Street 前進,左轉進入 Destination Road。在 Destination Road 直行 5 英里,就會看到右手邊的房子。地址是 743 Destination Road。

任何懂英文的人都能理解並照著執行——因為它是用英文寫的。文字算不上優美,但每條指令都清楚易懂。

電腦只懂機器語言#

問題在於電腦天生不懂英文,它只懂機器語言(machine language)。要指揮電腦做事,指令就必須用它的語言來寫。

而機器語言既晦澀又難以操作:

  • 它由原始的位元與位元組構成
  • 它隨架構而異

若要為 Intel x86 處理器寫一支機器語言程式,你必須弄清楚每條指令對應的數值、指令之間如何互動,以及無數低階細節。這種寫法既費力又笨重,而且完全不直覺。

三層翻譯器:組譯器、編譯器、高階語言#

要克服機器語言的複雜,需要的是翻譯器

組譯器與組合語言#

組譯器(assembler) 是機器語言翻譯器的一種形式——它把組合語言翻譯成機器可讀的程式碼。組合語言(assembly language) 比機器語言好懂,因為它用名稱來表示不同的指令與變數,而不是單純用數字。

但組合語言仍遠稱不上直覺:

  • 指令名稱極為晦澀難解。
  • 語言與架構綁死:正如 Intel x86 的機器語言不同於 Sparc 的機器語言,x86 組合語言也不同於 Sparc 組合語言。用某個處理器架構的組合語言寫的程式,在另一個架構上完全無法運作;x86 的程式要跑在 Sparc 上就得重寫。
  • 你仍必須懂目標處理器架構的許多低階細節,才寫得出有效的程式。

編譯器與高階語言#

編譯器(compiler) 是另一種翻譯器,它把高階語言轉換成機器語言,緩解了上述問題。

高階語言遠比組合語言直覺,而且同一份程式碼只需寫一次,就能被編譯成適用於各種處理器架構的機器語言。

C、C++、Fortran 都是高階語言的例子。以高階語言寫成的程式,讀起來比組合語言或機器語言更接近英文;但它仍必須嚴格遵守指令的措辭規則,否則編譯器就看不懂。