编程语言分类及python所属类型
編程語(yǔ)言分類及python所屬類型
?
編程語(yǔ)言主要從以下幾個(gè)角度為進(jìn)行分類:編譯型和解釋型、靜態(tài)語(yǔ)言和動(dòng)態(tài)語(yǔ)言、強(qiáng)類型定義語(yǔ)言和弱類型定義語(yǔ)言。
編譯和解釋的區(qū)別是什么?
編譯器是把源程序的每一條語(yǔ)句都編譯成機(jī)器語(yǔ)言,并保存成二進(jìn)制文件,這樣運(yùn)行時(shí)計(jì)算機(jī)可以直接以機(jī)器語(yǔ)言來(lái)運(yùn)行此程序,速度很快;
而解釋器則是只在執(zhí)行程序時(shí),才一條一條的解釋成機(jī)器語(yǔ)言給計(jì)算機(jī)來(lái)執(zhí)行,所以運(yùn)行速度是不如編譯后的程序運(yùn)行的快的。
這是因?yàn)橛?jì)算機(jī)不能直接認(rèn)識(shí)并執(zhí)行我們寫的語(yǔ)句,它只能認(rèn)識(shí)機(jī)器語(yǔ)言(是二進(jìn)制的形式)
?
?編譯型vs解釋型
編譯型
優(yōu)點(diǎn):編譯器一般會(huì)有預(yù)編譯的過(guò)程對(duì)代碼進(jìn)行優(yōu)化。因?yàn)榫幾g只做一次,運(yùn)行時(shí)不需要編譯,所以編譯型語(yǔ)言的程序執(zhí)行效率高。可以脫離語(yǔ)言環(huán)境獨(dú)立運(yùn)行。
缺點(diǎn):編譯之后如果需要修改就需要整個(gè)模塊重新編譯。編譯的時(shí)候根據(jù)對(duì)應(yīng)的運(yùn)行環(huán)境生成機(jī)器碼,不同的操作系統(tǒng)之間移植就會(huì)有問(wèn)題,需要根據(jù)運(yùn)行的操作系統(tǒng)環(huán)境編譯不同的可執(zhí)行文件。
解釋型
優(yōu)點(diǎn):有良好的平臺(tái)兼容性,在任何環(huán)境中都可以運(yùn)行,前提是安裝了解釋器(虛擬機(jī))。靈活,修改代碼的時(shí)候直接修改就可以,可以快速部署,不用停機(jī)維護(hù)。
缺點(diǎn):每次運(yùn)行的時(shí)候都要解釋一遍,性能上不如編譯型語(yǔ)言。
?
?一、低級(jí)語(yǔ)言與高級(jí)語(yǔ)言
最初的計(jì)算機(jī)程序都是用0和1的序列表示的,程序員直接使用的是機(jī)器指令,無(wú)需翻譯,從紙帶打孔輸入即可執(zhí)行得到結(jié)果。后來(lái)為了方便記憶,就將用0、1序列表示的機(jī)器指令都用符號(hào)助記,這些與機(jī)器指令一一對(duì)應(yīng)的助記符就成了匯編指令,從而誕生了匯編語(yǔ)言。無(wú)論是機(jī)器指令還是匯編指令都是面向機(jī)器的,統(tǒng)稱為低級(jí)語(yǔ)言。因?yàn)槭轻槍?duì)特定機(jī)器的機(jī)器指令的助記符,所以匯編語(yǔ)言是無(wú)法獨(dú)立于機(jī)器(特定的CPU體系結(jié)構(gòu))的。但匯編語(yǔ)言也是要經(jīng)過(guò)翻譯成機(jī)器指令才能執(zhí)行的,所以也有將運(yùn)行在一種機(jī)器上的匯編語(yǔ)言翻譯成運(yùn)行在另一種機(jī)器上的機(jī)器指令的方法,那就是交叉匯編技術(shù)。
高級(jí)語(yǔ)言是從人類的邏輯思維角度出發(fā)的計(jì)算機(jī)語(yǔ)言,抽象程度大大提高,需要經(jīng)過(guò)編譯成特定機(jī)器上的目標(biāo)代碼才能執(zhí)行,一條高級(jí)語(yǔ)言的語(yǔ)句往往需要若干條機(jī)器指令來(lái)完成。高級(jí)語(yǔ)言獨(dú)立于機(jī)器的特性是靠編譯器為不同機(jī)器生成不同的目標(biāo)代碼(或機(jī)器指令)來(lái)實(shí)現(xiàn)的。那具體的說(shuō),要將高級(jí)語(yǔ)言編譯到什么程度呢,這又跟編譯的技術(shù)有關(guān)了,既可以編譯成直接可執(zhí)行的目標(biāo)代碼,也可以編譯成一種中間表示,然后拿到不同的機(jī)器和系統(tǒng)上去執(zhí)行,這種情況通常又需要支撐環(huán)境,比如解釋器或虛擬機(jī)的支持,Java程序編譯成bytecode,再由不同平臺(tái)上的虛擬機(jī)執(zhí)行就是很好的例子。所以,說(shuō)高級(jí)語(yǔ)言不依賴于機(jī)器,是指在不同的機(jī)器或平臺(tái)上高級(jí)語(yǔ)言的程序本身不變,而通過(guò)編譯器編譯得到的目標(biāo)代碼去適應(yīng)不同的機(jī)器。從這個(gè)意義上來(lái)說(shuō),通過(guò)交叉匯編,一些匯編程序也可以獲得不同機(jī)器之間的可移植性,但這種途徑獲得的移植性遠(yuǎn)遠(yuǎn)不如高級(jí)語(yǔ)言來(lái)的方便和實(shí)用性大。
二、編譯與解釋
編譯是將源程序翻譯成可執(zhí)行的目標(biāo)代碼,翻譯與執(zhí)行是分開的;而解釋是對(duì)源程序的翻譯與執(zhí)行一次性完成,不生成可存儲(chǔ)的目標(biāo)代碼。這只是表象,二者背后的最大區(qū)別是:對(duì)解釋執(zhí)行而言,程序運(yùn)行時(shí)的控制權(quán)在解釋器而不在用戶程序;對(duì)編譯執(zhí)行而言,運(yùn)行時(shí)的控制權(quán)在用戶程序。
解釋具有良好的動(dòng)態(tài)特性和可移植性,比如在解釋執(zhí)行時(shí)可以動(dòng)態(tài)改變變量的類型、對(duì)程序進(jìn)行修改以及在程序中插入良好的調(diào)試診斷信息等,而將解釋器移植到不同的系統(tǒng)上,則程序不用改動(dòng)就可以在移植了解釋器的系統(tǒng)上運(yùn)行。同時(shí)解釋器也有很大的缺點(diǎn),比如執(zhí)行效率低,占用空間大,因?yàn)椴粌H要給用戶程序分配空間,解釋器本身也占用了寶貴的系統(tǒng)資源。
編譯器是把源程序的每一條語(yǔ)句都編譯成機(jī)器語(yǔ)言,并保存成二進(jìn)制文件,這樣運(yùn)行時(shí)計(jì)算機(jī)可以直接以機(jī)器語(yǔ)言來(lái)運(yùn)行此程序,速度很快;
而解釋器則是只在執(zhí)行程序時(shí),才一條一條的解釋成機(jī)器語(yǔ)言給計(jì)算機(jī)來(lái)執(zhí)行,所以運(yùn)行速度是不如編譯后的程序運(yùn)行的快的.
?
編譯型和解釋型:
我們先看看編譯型,其實(shí)它和匯編語(yǔ)言是一樣的:也是有一個(gè)負(fù)責(zé)翻譯的程序來(lái)對(duì)我們的源代碼進(jìn)行轉(zhuǎn)換,生成相對(duì)應(yīng)的可執(zhí)行代碼。這個(gè)過(guò)程說(shuō)得專業(yè)一點(diǎn),就稱為編譯(Compile),而負(fù)責(zé)編譯的程序自然就稱為編譯器(Compiler)。如果我們寫的程序代碼都包含在一個(gè)源文件中,那么通常編譯之后就會(huì)直接生成一個(gè)可執(zhí)行文件,我們就可以直接運(yùn)行了。但對(duì)于一個(gè)比較復(fù)雜的項(xiàng)目,為了方便管理,我們通常把代碼分散在各個(gè)源文件中,作為不同的模塊來(lái)組織。這時(shí)編譯各個(gè)文件時(shí)就會(huì)生成目標(biāo)文件(Object ? file)而不是前面說(shuō)的可執(zhí)行文件。一般一個(gè)源文件的編譯都會(huì)對(duì)應(yīng)一個(gè)目標(biāo)文件。這些目標(biāo)文件里的內(nèi)容基本上已經(jīng)是可執(zhí)行代碼了,但由于只是整個(gè)項(xiàng)目的一部分,所以我們還不能直接運(yùn)行。待所有的源文件的編譯都大功告成,我們就可以最后把這些半成品的目標(biāo)文件“打包”成一個(gè)可執(zhí)行文件了,這個(gè)工作由另一個(gè)程序負(fù)責(zé)完成,由于此過(guò)程好像是把包含可執(zhí)行代碼的目標(biāo)文件連接裝配起來(lái),所以又稱為鏈接(Link),而負(fù)責(zé)鏈接的程序就叫……就叫鏈接程序(Linker)。鏈接程序除了鏈接目標(biāo)文件外,可能還有各種資源,像圖標(biāo)文件啊、聲音文件啊什么的,還要負(fù)責(zé)去除目標(biāo)文件之間的冗余重復(fù)代碼,等等,所以……也是挺累的。鏈接完成之后,一般就可以得到我們想要的可執(zhí)行文件了。?
上面我們大概地介紹了編譯型語(yǔ)言的特點(diǎn),現(xiàn)在再看看解釋型。噢,從字面上看,“編譯”和“解釋”的確都有“翻譯”的意思,它們的區(qū)別則在于翻譯的時(shí)機(jī)安排不大一樣。打個(gè)比方:假如你打算閱讀一本外文書,而你不知道這門外語(yǔ),那么你可以找一名翻譯,給他足夠的時(shí)間讓他從頭到尾把整本書翻譯好,然后把書的母語(yǔ)版交給你閱讀;或者,你也立刻讓這名翻譯輔助你閱讀,讓他一句一句給你翻譯,如果你想往回看某個(gè)章節(jié),他也得重新給你翻譯。?
兩種方式,前者就相當(dāng)于我們剛才所說(shuō)的編譯型:一次把所有的代碼轉(zhuǎn)換成機(jī)器語(yǔ)言,然后寫成可執(zhí)行文件;而后者就相當(dāng)于我們要說(shuō)的解釋型:在程序運(yùn)行的前一刻,還只有源程序而沒有可執(zhí)行程序;而程序每執(zhí)行到源程序的某一條指令,則會(huì)有一個(gè)稱之為解釋程序的外殼程序?qū)⒃创a轉(zhuǎn)換成二進(jìn)制代碼以供執(zhí)行,總言之,就是不斷地解釋、執(zhí)行、解釋、執(zhí)行……所以,解釋型程序是離不開解釋程序的。像早期的BASIC就是一門經(jīng)典的解釋型語(yǔ)言,要執(zhí)行BASIC程序,就得進(jìn)入BASIC環(huán)境,然后才能加載程序源文件、運(yùn)行。解釋型程序中,由于程序總是以源代碼的形式出現(xiàn),因此只要有相應(yīng)的解釋器,移植幾乎不成問(wèn)題。編譯型程序雖然源代碼也可以移植,但前提是必須針對(duì)不同的系統(tǒng)分別進(jìn)行編譯,對(duì)于復(fù)雜的工程來(lái)說(shuō),的確是一件不小的時(shí)間消耗,況且很可能一些細(xì)節(jié)的地方還是要修改源代碼。而且,解釋型程序省卻了編譯的步驟,修改調(diào)試也非常方便,編輯完畢之后即可立即運(yùn)行,不必像編譯型程序一樣每次進(jìn)行小小改動(dòng)都要耐心等待漫長(zhǎng)的Compiling…Linking…這樣的編譯鏈接過(guò)程。不過(guò)凡事有利有弊,由于解釋型程序是將編譯的過(guò)程放到執(zhí)行過(guò)程中,這就決定了解釋型程序注定要比編譯型慢上一大截,像幾百倍的速度差距也是不足為奇的。?
編譯型與解釋型,兩者各有利弊。前者由于程序執(zhí)行速度快,同等條件下對(duì)系統(tǒng)要求較低,因此像開發(fā)操作系統(tǒng)、大型應(yīng)用程序、數(shù)據(jù)庫(kù)系統(tǒng)等時(shí)都采用它,像C/C++、Pascal/Object ? Pascal(Delphi)、VB等基本都可視為編譯語(yǔ)言,而一些網(wǎng)頁(yè)腳本、服務(wù)器腳本及輔助開發(fā)接口這樣的對(duì)速度要求不高、對(duì)不同系統(tǒng)平臺(tái)間的兼容性有一定要求的程序則通常使用解釋性語(yǔ)言,如Java、JavaScript、VBScript、Perl、Python等等。?
但既然編譯型與解釋型各有優(yōu)缺點(diǎn)又相互對(duì)立,所以一批新興的語(yǔ)言都有把兩者折衷起來(lái)的趨勢(shì),例如Java語(yǔ)言雖然比較接近解釋型語(yǔ)言的特征,但在執(zhí)行之前已經(jīng)預(yù)先進(jìn)行一次預(yù)編譯,生成的代碼是介于機(jī)器碼和Java源代碼之間的中介代碼,運(yùn)行的時(shí)候則由JVM(Java的虛擬機(jī)平臺(tái),可視為解釋器)解釋執(zhí)行。它既保留了源代碼的高抽象、可移植的特點(diǎn),又已經(jīng)完成了對(duì)源代碼的大部分預(yù)編譯工作,所以執(zhí)行起來(lái)比“純解釋型”程序要快許多。而像VB6(或者以前版本)、C#這樣的語(yǔ)言,雖然表面上看生成的是.exe可執(zhí)行程序文件,但VB6編譯之后實(shí)際生成的也是一種中介碼,只不過(guò)編譯器在前面安插了一段自動(dòng)調(diào)用某個(gè)外部解釋器的代碼(該解釋程序獨(dú)立于用戶編寫的程序,存放于系統(tǒng)的某個(gè)DLL文件中,所有以VB6編譯生成的可執(zhí)行程序都要用到它),以解釋執(zhí)行實(shí)際的程序體。C#(以及其它.net的語(yǔ)言編譯器)則是生成.net目標(biāo)代碼,實(shí)際執(zhí)行時(shí)則由.net解釋系統(tǒng)(就像JVM一樣,也是一個(gè)虛擬機(jī)平臺(tái))進(jìn)行執(zhí)行。當(dāng)然.net目標(biāo)代碼已經(jīng)相當(dāng)“低級(jí)”,比較接近機(jī)器語(yǔ)言了,所以仍將其視為編譯語(yǔ)言,而且其可移植程度也沒有Java號(hào)稱的這么強(qiáng)大,Java號(hào)稱是“一次編譯,到處執(zhí)行”,而.net則是“一次編碼,到處編譯”。呵呵,當(dāng)然這些都是題外話了。總之,隨著設(shè)計(jì)技術(shù)與硬件的不斷發(fā)展,編譯型與解釋型兩種方式的界限正在不斷變得模糊。
?
動(dòng)態(tài)語(yǔ)言和靜態(tài)語(yǔ)言:
通常我們所說(shuō)的動(dòng)態(tài)語(yǔ)言、靜態(tài)語(yǔ)言是指動(dòng)態(tài)類型語(yǔ)言和靜態(tài)類型語(yǔ)言。
(1)動(dòng)態(tài)類型語(yǔ)言:動(dòng)態(tài)類型語(yǔ)言是指在運(yùn)行期間才去做數(shù)據(jù)類型檢查的語(yǔ)言,也就是說(shuō),在用動(dòng)態(tài)類型的語(yǔ)言編程時(shí),永遠(yuǎn)也不用給任何變量指定數(shù)據(jù)類型,該語(yǔ)言會(huì)在你第一次賦值給變量時(shí),在內(nèi)部將數(shù)據(jù)類型記錄下來(lái)。Python和Ruby就是一種典型的動(dòng)態(tài)類型語(yǔ)言,其他的各種腳本語(yǔ)言如VBScript也多少屬于動(dòng)態(tài)類型語(yǔ)言。
(2)靜態(tài)類型語(yǔ)言:靜態(tài)類型語(yǔ)言與動(dòng)態(tài)類型語(yǔ)言剛好相反,它的數(shù)據(jù)類型是在編譯其間檢查的,也就是說(shuō)在寫程序時(shí)要聲明所有變量的數(shù)據(jù)類型,C/C++是靜態(tài)類型語(yǔ)言的典型代表,其他的靜態(tài)類型語(yǔ)言還有C#、JAVA等。
?
強(qiáng)類型定義語(yǔ)言和弱類型定義語(yǔ)言:
(1)強(qiáng)類型定義語(yǔ)言:強(qiáng)制數(shù)據(jù)類型定義的語(yǔ)言。也就是說(shuō),一旦一個(gè)變量被指定了某個(gè)數(shù)據(jù)類型,如果不經(jīng)過(guò)強(qiáng)制轉(zhuǎn)換,那么它就永遠(yuǎn)是這個(gè)數(shù)據(jù)類型了。舉個(gè)例子:如果你定義了一個(gè)整型變量a,那么程序根本不可能將a當(dāng)作字符串類型處理。強(qiáng)類型定義語(yǔ)言是類型安全的語(yǔ)言。
(2)弱類型定義語(yǔ)言:數(shù)據(jù)類型可以被忽略的語(yǔ)言。它與強(qiáng)類型定義語(yǔ)言相反, 一個(gè)變量可以賦不同數(shù)據(jù)類型的值。
強(qiáng)類型定義語(yǔ)言在速度上可能略遜色于弱類型定義語(yǔ)言,但是強(qiáng)類型定義語(yǔ)言帶來(lái)的嚴(yán)謹(jǐn)性能夠有效的避免許多錯(cuò)誤。另外,“這門語(yǔ)言是不是動(dòng)態(tài)語(yǔ)言”與“這門語(yǔ)言是否類型安全”之間是完全沒有聯(lián)系的!
例如:Python是動(dòng)態(tài)語(yǔ)言,是強(qiáng)類型定義語(yǔ)言(類型安全的語(yǔ)言); VBScript是動(dòng)態(tài)語(yǔ)言,是弱類型定義語(yǔ)言(類型不安全的語(yǔ)言); JAVA是靜態(tài)語(yǔ)言,是強(qiáng)類型定義語(yǔ)言(類型安全的語(yǔ)言)。
?
通過(guò)上面這些介紹,我們可以得出,python是一門動(dòng)態(tài)解釋性的強(qiáng)類型定義語(yǔ)言。
?
posted on 2017-09-06 12:10 Ella_Wu 閱讀(...) 評(píng)論(...) 編輯 收藏轉(zhuǎn)載于:https://www.cnblogs.com/wuaihua/p/7484051.html
總結(jié)
以上是生活随笔為你收集整理的编程语言分类及python所属类型的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
                            
                        - 上一篇: mogodbshell中数组对象查询修改
 - 下一篇: golang ffmpeg 做网络直播