什麼是編程語言的強類型,弱類型

給你來個例子把 弱類型語言vbs: a=1 b=a+"1"+"a" //結果是11a,這裏 a 成了字符串 c=a+1 //結果是2 ,這裏a則是數字型 強類型語言:c# int a=2 string b=a.ToString()+"1"+"a" int c=a+1 看到了嗎?區分大小寫,須要實現申明類型外,一個重要的區別是,弱類型的語言的東西沒有明顯的類型,他能隨着環境的不一樣,自動變換類型 而強類型則沒這樣的規定,不一樣類型間的操做有嚴格定義,只有相同類型的變量才能操做,雖然系統也有必定的默認轉換,當絕沒有弱類型那麼隨便 ps:弱類型代碼簡單,但由於變量沒有肯定的類型,因此容易出錯!強類型代碼複雜(好比:轉換日期顯示格式 (convert.toDatetime("2007-1-1 08:08:08")).ToString("yyyy-MM-dd"),呵呵你能夠看到這種寫法至關麻煩),但由於有嚴格定義因此不容易出錯python

 

編譯型和解釋型c++


咱們先看看編譯型,其實它和彙編語言是同樣的:也是有一個負責翻譯的程序來對咱們的源代碼進行轉換,生成相對應的可執行代碼。這個過程說得專業一點,就稱爲編譯(Compile),而負責編譯的程序天然就稱爲編譯器(Compiler)。若是咱們寫的程序代碼都包含在一個源文件中,那麼一般編譯以後就會直接生成一個可執行文件,咱們就能夠直接運行了。但對於一個比較複雜的項目,爲了方便管理,咱們一般把代碼分散在各個源文件中,做爲不一樣的模塊來組織。這時編譯各個文件時就會生成目標文件(Object   file)而不是前面說的可執行文件。通常一個源文件的編譯都會對應一個目標文件。這些目標文件裏的內容基本上已是可執行代碼了,但因爲只是整個項目的一部分,因此咱們還不能直接運行。待全部的源文件的編譯都大功告成,咱們就能夠最後把這些半成品的目標文件「打包」成一個可執行文件了,這個工做由另外一個程序負責完成,因爲此過程好像是把包含可執行代碼的目標文件鏈接裝配起來,因此又稱爲連接(Link),而負責連接的程序就叫……就叫連接程序(Linker)。連接程序除了連接目標文件外,可能還有各類資源,像圖標文件啊、聲音文件啊什麼的,還要負責去除目標文件之間的冗餘重複代碼,等等,因此……也是挺累的。連接完成以後,通常就能夠獲得咱們想要的可執行文件了。 

上面咱們大概地介紹了編譯型語言的特色,如今再看看解釋型。噢,從字面上看,「編譯」和「解釋」的確都有「翻譯」的意思,它們的區別則在於翻譯的時機安排不大同樣。打個比方:假如你打算閱讀一本外文書,而你不知道這門外語,那麼你能夠找一名翻譯,給他足夠的時間讓他從頭至尾把整本書翻譯好,而後把書的母語版交給你閱讀;或者,你也馬上讓這名翻譯輔助你閱讀,讓他一句一句給你翻譯,若是你想往回看某個章節,他也得從新給你翻譯。 

兩種方式,前者就至關於咱們剛纔所說的編譯型:一次把全部的代碼轉換成機器語言,而後寫成可執行文件;然後者就至關於咱們要說的解釋型:在程序運行的前一刻,還只有源程序而沒有可執行程序;而程序每執行到源程序的某一條指令,則會有一個稱之爲解釋程序的外殼程序將源代碼轉換成二進制代碼以供執行,總言之,就是不斷地解釋、執行、解釋、執行……因此,解釋型程序是離不開解釋程序的。像早期的BASIC就是一門經典的解釋型語言,要執行BASIC程序,就得進入BASIC環境,而後才能加載程序源文件、運行。解釋型程序中,因爲程序老是以源代碼的形式出現,所以只要有相應的解釋器,移植幾乎不成問題。編譯型程序雖然源代碼也能夠移植,但前提是必須針對不一樣的系統分別進行編譯,對於複雜的工程來講,的確是一件不小的時間消耗,何況極可能一些細節的地方仍是要修改源代碼。並且,解釋型程序省卻了編譯的步驟,修改調試也很是方便,編輯完畢以後便可當即運行,沒必要像編譯型程序同樣每次進行小小改動都要耐心等待漫長的Compiling…Linking…這樣的編譯連接過程。不過凡事有利有弊,因爲解釋型程序是將編譯的過程放到執行過程當中,這就決定了解釋型程序註定要比編譯型慢上一大截,像幾百倍的速度差距也是不足爲奇的。 

編譯型與解釋型,二者各有利弊。前者因爲程序執行速度快,同等條件下對系統要求較低,所以像開發操做系統、大型應用程序、數據庫系統等時都採用它,像C/C++、Pascal/Object   Pascal(Delphi)、VB等基本均可視爲編譯語言,而一些網頁腳本、服務器腳本及輔助開發接口這樣的對速度要求不高、對不一樣系統平臺間的兼容性有必定要求的程序則一般使用解釋性語言,如Java、JavaScript、VBScript、Perl、Python等等。 

但既然編譯型與解釋型各有優缺點又相互對立,因此一批新興的語言都有把二者折衷起來的趨勢,例如Java語言雖然比較接近解釋型語言的特徵,但在執行以前已經預先進行一次預編譯,生成的代碼是介於機器碼和Java源代碼之間的中介代碼,運行的時候則由JVM(Java的虛擬機平臺,可視爲解釋器)解釋執行。它既保留了源代碼的高抽象、可移植的特色,又已經完成了對源代碼的大部分預編譯工做,因此執行起來比「純解釋型」程序要快許多。而像VB6(或者之前版本)、C#這樣的語言,雖然表面上看生成的是.exe可執行程序文件,但VB6編譯以後實際生成的也是一種中介碼,只不過編譯器在前面安插了一段自動調用某個外部解釋器的代碼(該解釋程序獨立於用戶編寫的程序,存放於系統的某個DLL文件中,全部以VB6編譯生成的可執行程序都要用到它),以解釋執行實際的程序體。C#(以及其它.net的語言編譯器)則是生成.net目標代碼,實際執行時則由.net解釋系統(就像JVM同樣,也是一個虛擬機平臺)進行執行。固然.net目標代碼已經至關「低級」,比較接近機器語言了,因此仍將其視爲編譯語言,並且其可移植程度也沒有Java號稱的這麼強大,Java號稱是「一次編譯,處處執行」,而.net則是「一次編碼,處處編譯」。呵呵,固然這些都是題外話了。總之,隨着設計技術與硬件的不斷髮展,編譯型與解釋型兩種方式的界限正在不斷變得模糊。數據庫

動態語言和靜態語言
  一般咱們所說的動態語言、靜態語言是指動態類型語言和靜態類型語言。編程

(1)動態類型語言:動態類型語言是指在運行期間纔去作數據類型檢查的語言,也就是說,在用動態類型的語言編程時,永遠也不用給任何變量指定數據類型,該語言會在你第一次賦值給變量時,在內部將數據類型記錄下來。Python和Ruby就是一種典型的動態類型語言,其餘的各類腳本語言如VBScript也多少屬於動態類型語言。c#

(2)靜態類型語言:靜態類型語言與動態類型語言恰好相反,它的數據類型是在編譯其間檢查的,也就是說在寫程序時要聲明全部變量的數據類型,C/C++是靜態類型語言的典型表明,其餘的靜態類型語言還有C#、JAVA等。安全

對於動態語言與靜態語言的區分,套用一句流行的話就是:Static typing when possible, dynamic typing when needed。ruby

強類型定義語言和弱類型定義語言服務器

(1)強類型定義語言:強制數據類型定義的語言。也就是說,一旦一個變量被指定了某個數據類型,若是不通過強制轉換,那麼它就永遠是這個數據類型了。舉個例子:若是你定義了一個整型變量a,那麼程序根本不可能將a看成字符串類型處理。強類型定義語言是類型安全的語言。函數

(2)弱類型定義語言:數據類型能夠被忽略的語言。它與強類型定義語言相反, 一個變量能夠賦不一樣數據類型的值。性能

強類型定義語言在速度上可能略遜色於弱類型定義語言,可是強類型定義語言帶來的嚴謹性可以有效的避免許多錯誤。另外,「這門語言是否是動態語言」與「這門語言是否類型安全」之間是徹底沒有聯繫的!
例如:Python是動態語言,是強類型定義語言(類型安全的語言); VBScript是動態語言,是弱類型定義語言(類型不安全的語言); JAVA是靜態語言,是強類型定義語言(類型安全的語言)。

 

靜態類型定義語言

一種在編譯時,數據類型是固定的語言。大多數靜態類型定義語言強制這一點,它要求你在使用全部變量以前要聲明它們的數據類型。Java和C是靜態類型定義語言。

動態類型定義語言

一種在執行期間纔去發現數據類型的語言,與靜態類型定義相反。VBScript和Python是動態類型定義的,由於它們是在第一次給一個變量賦值的時候找出它的類型的。

強類型定義語言

一種老是強制類型定義的語言。Java和Python是強制類型定義的。若是你有一個整數,若是不顯示地進行轉換,你不能將其視爲一個字符串。

弱類型定義語言

一種類型能夠被忽略的語言,與強類型定義相反。VBScript是弱類型定義的。在VBScript中,能夠將字符串'12'和整數3進行鏈接獲得字符串'123',而後能夠把它當作整數123,而不須要顯示轉換。但其實它們的類型沒有改變,VB只是在判斷出一個表達式含有不一樣類型的變量以後,自動在這些變量前加了一個clong()或(int)()這樣的轉換函數而已.能作到這一點實際上是歸功於VB的編譯器的智能化而已,這並不是是VB語言自己的長處或短處.

結論:

靜態是類型編譯時判斷;動態是類型運行時判斷;強類型是類型獨立,不輕易轉化;弱類型是類型不嚴格區分,通常是隻要大小放得下,就能夠轉化。這種是彙編級的觀點。面向對象的觀點並不是這樣的,對象並非大小差很少就是類型兼容,而是關鍵的接口要相同才叫類型兼容。

動態語言並不是是弱類型,這是不等價的。剛好的,通常動態語言都是強類型語言,由於都是遵守面向對象的觀點來設計對象的。

動態語言的劣勢很明顯,就是缺乏開發環境,運行效率差,固然語言設計上也不完美(靜態語言何止千萬,但c++也就一個)。

優點也很明顯,就是編寫容易,層次高,接近天然語義。動態類型語言效率低下的緣由,不在於變量的類型是動態的,而在於對象的方法是動態聯編的,在這一點上動態類型語言和Java沒什麼不一樣。

靜態類型語言的優點到底是什麼?

觀點一:靜態類型語言由於類型強制聲明,因此IDE能夠作到很好的代碼感知能力,由於有IDE的撐腰,因此開發大型系統,複雜系統比較有保障。

對於像Java來講,IDEA/Eclipse確實在代碼感知能力上面已經很是強了,這無疑可以增長對大型系統複雜系統的掌控能力。可是除了Java擁有這麼強的IDE武器以外,彷佛其餘語言歷來沒有這麼強的IDE。C#的Visual Studio在GUI開發方面和Wizard方面很強,可是代碼感知能力上和Eclipse差的不是一點半點。至於Visual C++根本就是一個編譯器而已,羞於說起Visual這個字眼。更不要說那麼多C/C++開發人員都是操起vi吭哧吭哧寫了幾十萬行代碼呢。特別是像Linux Kernel這種幾百萬行代碼,也就是用vi寫出來的阿,夠複雜,夠大型,夠長生命週期的吧。

觀點二:靜態語言相對比較封閉的特色,使得第三方開發包對代碼的侵害性能夠降到很低。動態語言在這點上表現的就比較差,我想你們都有過從網上下載某個JS包,而後放到項目代碼裏發生衝突的經歷

也就是說靜態類型語言能夠保障package的命名空間分割,從而避免命名衝突,代碼的良好隔離性。可是這個觀點也缺少說服力。

靜態類型語言中C,VB都缺少良好的命名空間分割,容易產生衝突,可是並無影響他們作出來的系統就不夠大,不夠複雜。

而Visual C++開發的DLL版本衝突也是臭名昭著的,彷佛C++的命名空間沒有給它帶來很大的幫助。

而動態類型語言中Ruby/Python/Perl都有比較好的命名空間,特別是Python和Perl,例如CPAN上面的第三方庫成噸成噸的,也歷來沒有據說什麼衝突的問題。

誠然像PHP,JavaScript這樣缺少命名空間的動態語言很容易出現問題,可是這彷佛是由於他們缺少OO機制致使的,而不是由於他們動態類型致使的吧?

說到大型系統,複雜業務邏輯系統,Google公司不少東西都是用python開發的,這也證實了動態類型語言並不是不能作大型的複雜的系統。其實我我的認爲:

動態類型語言,特別是高級動態類型語言,反而可以讓人們不須要分心去考慮程序編程問題,而集中精力思考業務邏輯實現,即思考過程即實現過程,用DSL描述問題的過程就是編程的過程,這方面像Unix Shell,ruby,SQL,甚至PHP都是相應領域當之無愧的DSL語言。而顯然靜態類型語言基本都不知足這個要求。

那靜態類型語言的優點到底是什麼呢?我認爲就是執行效率很是高。因此但凡須要關注執行性能的地方就得用靜態類型語言。其餘方面彷佛沒有什麼特別的優點。

 

給你來個例子把

弱類型語言vbs:
 a=1
 b=a+"1"+"a" //結果是11a,這裏 a 成了字符串
 c=a+1 //結果是2 ,這裏a則是數字型

強類型語言:c#
int a=2
string b=a.ToString()+"1"+"a"
int c=a+1

看到了嗎?區分大小寫,須要實現申明類型外,一個重要的區別是,弱類型的語言的東西沒有明顯的類型,他能隨着環境的不一樣,自動變換類型
而強類型則沒這樣的規定,不一樣類型間的操做有嚴格定義,只有相同類型的變量才能操做,雖然系統也有必定的默認轉換,當絕沒有弱類型那麼隨便

ps:弱類型代碼簡單,但由於變量沒有肯定的類型,因此容易出錯!強類型代碼複雜(好比:轉換日期顯示格式 (convert.toDatetime("2007-1-1 08:08:08")).ToString("yyyy-MM-dd"),呵呵你能夠看到這種寫法至關麻煩),但由於有嚴格定義因此不容易出錯
相關文章
相關標籤/搜索