學(xué)習(xí)編程的第一課,就是介紹這門編程語(yǔ)言的特點(diǎn)。翻開C語(yǔ)言的教程,你就會(huì)在他的特性中發(fā)現(xiàn)這樣一點(diǎn):擁有很強(qiáng)的可移植性。然后翻開java語(yǔ)言的教程,你也會(huì)發(fā)現(xiàn)可移植性高的描述。再多翻幾本手冊(cè),你會(huì)發(fā)現(xiàn)可移植性好像是編程語(yǔ)言都具有的一種特性。那么編程語(yǔ)言在提到自身的優(yōu)勢(shì)的時(shí)候,為什么要把這樣一個(gè)近乎人人都有的特性提出來(lái)呢?他們之間又有什么差異呢?請(qǐng)聽小編慢慢分解。
編譯&解釋
一門編程語(yǔ)言從源代碼到機(jī)器可執(zhí)行的程序,有兩種方式,一種是編譯,一種是解釋,這并不是對(duì)編程語(yǔ)言的一種界定,因?yàn)橛行┱Z(yǔ)言既可以編譯執(zhí)行也可以解釋執(zhí)行(有種說法是,一些編程語(yǔ)言在開發(fā)的時(shí)候使用解釋的方式進(jìn)行調(diào)試,在后期再改成編譯方式執(zhí)行,這樣能快速調(diào)整語(yǔ)言的特性,比如JavaScript的V8引擎就引入了即時(shí)編譯功能)。就像作一道菜,源代碼就是菜譜,編譯執(zhí)行就是先將代碼遍掃一遍,然后進(jìn)行執(zhí)行,就像先把菜譜看一遍,學(xué)會(huì)了再執(zhí)行;而解釋執(zhí)行是代碼逐行解釋,就像是看菜譜的步驟,一個(gè)步驟看一遍,逐步執(zhí)行。理想情況下編譯執(zhí)行和解釋執(zhí)行應(yīng)該是效率相同的,但是解釋執(zhí)行并不能預(yù)測(cè)到后面的結(jié)果,所以需要花費(fèi)一些算力去進(jìn)行優(yōu)化(比如有有一個(gè)變量,在某處用完后就可以釋放了,在編譯執(zhí)行過程中就可以直接釋放,而解釋執(zhí)行就不能釋放,因?yàn)樗恢肋@個(gè)變量后面是否還會(huì)使用)。
編譯和解釋的區(qū)別不僅僅在運(yùn)行過程上,在運(yùn)行方式上也有區(qū)別:編譯是將高級(jí)語(yǔ)言轉(zhuǎn)化成專屬于目標(biāo)機(jī)器的機(jī)器語(yǔ)言。解釋則是直接執(zhí)行高級(jí)語(yǔ)言(執(zhí)行高級(jí)語(yǔ)言的過程,是將單行代碼轉(zhuǎn)換為機(jī)器語(yǔ)言的過程)。
可移植性
講了那么多,還是沒有提到可移植性。但實(shí)際上,上面的內(nèi)容正是決定可移植性的一個(gè)因素。我們知道,編譯過程,是將一門高級(jí)語(yǔ)言轉(zhuǎn)化為目標(biāo)機(jī)器語(yǔ)言,而中間需要編譯器的介入。實(shí)際上,不同的機(jī)器使用的機(jī)器語(yǔ)言是不同的,所以使用的編譯器也是不同的,高級(jí)語(yǔ)言的通用特性,就是高級(jí)語(yǔ)言可以通過不同的編譯器轉(zhuǎn)換成不同的機(jī)器語(yǔ)言。雖然最終的編譯結(jié)果不同,但源代碼是相同的,運(yùn)行結(jié)果也是相同的,所以高級(jí)語(yǔ)言的源代碼基本都具有代碼可移植性。
而解釋過程就更加厲害了,一門語(yǔ)言要適用于一個(gè)平臺(tái),首先要在這個(gè)平臺(tái)上實(shí)現(xiàn)相應(yīng)的解釋器。然后,我們知道,解釋型語(yǔ)言是直接用解釋器執(zhí)行高級(jí)語(yǔ)言的,這也就決定了同樣的代碼可以在不同的機(jī)器上運(yùn)行出相同的效果。
另一個(gè)因素
實(shí)際上上面的內(nèi)容只是一種比較理想的存在,Windows和linux的內(nèi)核是完全不同的,他們能提供的系統(tǒng)操作也是不同的。所以要適配這樣的不同平臺(tái)的代碼,實(shí)際上還是得進(jìn)行一定的修改。
一處編譯,處處執(zhí)行
還有一種神奇的存在,號(hào)稱一處編譯處處執(zhí)行,那就是java。關(guān)于java的一處編譯處處執(zhí)行,可以參考小編的這篇文章:一處編譯處處運(yùn)行如何實(shí)現(xiàn)?淺析語(yǔ)言的跨平臺(tái)性
java的這個(gè)特性,又叫跨平臺(tái)可移植性,是一種比較高級(jí)的存在。c語(yǔ)言這種編譯型語(yǔ)言和JavaScript這種解釋型語(yǔ)言的優(yōu)點(diǎn)被其融合在一起。java在編譯過程中避免了解釋型語(yǔ)言的一些問題,使最后編譯出來(lái)的字節(jié)碼在解釋執(zhí)行的時(shí)候盡可能的達(dá)到接近編譯執(zhí)行的速度。而在最后執(zhí)行的過程中使用解釋執(zhí)行,繼承了解釋型語(yǔ)言的跨平臺(tái)的優(yōu)點(diǎn)。
由于python有一個(gè)版本(JPython)是使用java實(shí)現(xiàn)的,這個(gè)版本也可以將python編譯成java字節(jié)碼文件,然后再jvm上解釋執(zhí)行,所以JPython也是這樣的高級(jí)存在。
小結(jié)
接下來(lái)是對(duì)本文章的一個(gè)總結(jié):
可移植性,是高級(jí)語(yǔ)言都有的一個(gè)特點(diǎn),只要具有可移植性,他的源代碼就可以在不同的平臺(tái)編譯出相應(yīng)的結(jié)果。
跨平臺(tái)性,是解釋型語(yǔ)言的一個(gè)特點(diǎn),只要目標(biāo)平臺(tái)擁有對(duì)應(yīng)的解釋器,源代碼就可以在這個(gè)平臺(tái)運(yùn)行出相應(yīng)的結(jié)果。