01:引言-[程式設計語言]-摘記&註解

來源:互聯網
上載者:User

標籤:style   blog   http   java   color   使用   

閱讀導航

本系列其他文章目錄請戳這裡。

1.機器語言>組合語言>進階語言

語言是人與人的一種交流工具,就比如我現在用漢語來寫這篇博文來交流探討技術問題;程式設計語言也是如此,只是交流對象不是人而是機器。

我可以用漢語來寫博文,也可以用英語來寫(假如我英語熟練);我可以用PHP來寫一個網站,也可以用ASP.NET來寫。

這就說明語言的本質就是一種交流工具,而我選擇哪種語言來交流並不會影響我要的結果。然而在實際中到底要選用那個語言確要根據具體情況而定,這是個成本問題,比如我如果今天腦子抽筋要用日語,那我寫著也累(關鍵是也不會)、讀者或許也會罵娘了。

早期的電腦是一台超級龐然大物,能耗抵得上一家小型工廠,而計算能力確不如今天的一台手持計算機。也就是當時人力成本要遠遠低於這台機器的機器成本,也就決定了當時是以機器為中心,而不是人。所以人們用電腦能直接理解的機器語言來編寫程式。

這裡有一個計算兩個整數的最大公約數的栗子(MIPS R4000處理器的機器語言),16進位形式如下:

1 2dbdffd0 afbf0014 oc1002a8 00000000 0c1002a8 afa2001c 8fa4001c2 00401825 10820008 0064082a 10200003 00000000 10000002 008320233 00641823 1483fffa 0064082a 0c1002b2 00000000 8fbf0014 27bd00204 03e00008 00001025

這些機器語言對人的閱讀和理解相當的不友好。當程式越來越複雜,人們迫切需要一種簡單不易出錯的記法形式,於是人們創造了組合語言,用簡短的詞語來助記機器操作。

用MIPS R4000處理器的組合語言重寫上面的栗子如下:

 1    addiu  sp,sp-32 2    sw     ra,20(sp) 3    jal    getint 4    nop 5    jal    getint 6    sw     v0,28(sp) 7    lw     a0,28(sp) 8    move   v1,v0 9    beq    a0,v0,D10    slt    at,v1,a011 A: beq    at,zero,B12    nop    13    b      C14    subu   a0,a0,v115 B: subu   v1,v1,a016 C: bne    a0,v1,A17    slt    at,v1,a018 D: jal    putint19    nop20    lw     ra,20(sp)21    addiu  sp,sp,3222    jr     ra23    move   v0,zer

對於這個栗子,閱讀和理解上明顯要比機器語言要容易得多。然而這種編碼形式電腦是不識別的,需要一種叫做“彙編器”的程式來翻譯成對應的機器的機器語言才能執行。

這種一個彙編指令對應一個機器之路的關係還是顯而易見的,對於不同的電腦,則還需不同的組合語言來編寫;這個時代的程式設計仍然是以機器為中心,程式員也許要以機器的思維來解決問題。

就如同機器語言到組合語言的過渡一樣,程式越來越複雜、各種類型的電腦越來越多,為每一種機器都編寫程式也越來越困難、人力成本也越來越大。

根據電腦科學領域慣用的抽象原則,人們需要一個中介層來隔離某一個計算操作對具體機器的具體操作指令的這種對應關係,也就是這個中介層需要獨立於具體的機器操作。隨後人們就創造出了進階程式設計語言來做這麼一個中介層,由於剝離了計算操作到具體機器操作的對應關係,但是機器具體執行的依然還是機器操作,那麼也就需要一個更“進階的翻譯器”來做這項翻譯工作,這個進階的翻譯器就是現在所說的編譯器。

由於這種翻譯工作是由機器來完成的,在編譯器出現的早期時候,人們總是能夠寫出比進階語言代碼更高效的相應的組合語言(畢竟早期的時候電腦的計算能力還一種奢侈的資源)。但是隨著程式進一步的擴大、硬體效能的提升、編譯器的最佳化、程式的維護成本等等變化,這種效能差異和人力成本相比慢慢也就顯得微不足道了。

現在想一想,當初c++面世的時候、基於虛擬機器技術的java出現時也是這麼一種情況。

自從進階程式設計語言出現以後,程式設計慢慢開始從以機器為中心向以人為中心轉變。

2.編譯和解釋

按照抽象的觀點來看,進階語言的編譯和執行大致是如下的樣子:

編譯器把來源程式翻譯成目標程式(典型的是機器語言程式)後就隱退了,後面的程式的運行中就不在需要編譯器的存在了。

解譯器是另外一種實現進階語言的方式:

和編譯器不同的是,解譯器一直全程守候。解譯器本身相當於一個“虛擬機器”,它的“機器語言”就是來源程式的進階語言。

和編譯器相比,解譯器可以有更大的靈活性。它可以輕易地做到在程式運行初期來產生某一塊新的代碼,然後再後續的某一個時間去執行它;以及把一些決策延遲到運行時再去做決定。和解譯器相對應,編譯型的語言通常可以帶來較好的效能,它可以在編譯時間期就把一些決策確定下來,比如一些記憶體布局。

雖然兩者的概念很清晰,也有較大的差異性,然而現實中有些語言是“混合型”的,流程大致如下:

如果初期階段的翻譯器比較簡單,則我們把它稱為解釋型語言;如果翻譯階段複雜,則成為編譯型語言。

然而簡單和複雜本身是個形容詞,而不能可量化。完全有可能出現一個複雜的翻譯器負責中繼語言程式的產生,一個複雜的虛擬機器(解譯器)來執行中繼語言,JAVA、.NET也正是這種實現方式。

  • 連接器和前置處理器

我們所用的進階語言所寫的程式通常還需要一個庫(包含一些IO、網路等等的操作),在編譯的時候就需要把我們寫的來源程式和庫程式連結到一起來產生目標代碼,比如我要讀寫檔案,則需要連結IO相關的庫程式。通常情況下目標代碼為組合語言而不是機器語言,這種方式更有利於偵錯工具,也便於閱讀,更能把編譯器和機器語言檔案格式的變化隔離開來。

前置處理器可以提供一種條件編譯的功能,比如C#中編譯條件#if DEBUG這些東西,再如C、C++中的宏機制也是屬於先行編譯的範濤。

3.程式語言的設計實現以及分類

現實中語言的設計和實現總是有不可調和的矛盾,從設計角度來看總是希望一個語言能有更強大的表達能力,然而卻總是受到語言的實現制約。這根本原因大概也許是以人為中心和以機器為中心的矛盾吧,因為你的語言的執行最終還是離不開機器的執行,所以語言設計者也是不得不在這兩者中間尋求平衡。

依據現有的計算模型(運算產生結果或運算影響結果),大致分為兩大類(當然這些所謂的分類也是從不同角度得來的,如果你站在另外的角度看,或許就是另外一番景象了)說明式語言和命令式語言。從某種的角度看,說明式語言明顯要更“進階”,因為它更貼近使用者-程式員,而更遠離實現者-語言設計者。然而現在的語言還是命令式佔據著統治地位,主要是因為實現的難度、效能的要求等原因制約著說明式語言的發展。上層是抽象的進階語言,下層是實現的細節,抽象層級越高,實現的難度則越大,因為你要隔離隱藏的細節越複雜。

函數式語言是說明式語言中的一個,近年它的熱度也是急劇上升來著;我們熟知的C、C++、JAVA,C#等都是屬於馮諾依曼體系的範濤,當然也是命令式語言的子集。和函數式語言中的把函數和數值作為語言的一等公民(可以賦值為給變數、作為參數傳遞、作為傳回值處理)不一樣的是,馮諾依曼語言的中的基本操作是指派陳述式,它們通過“副作用”去影響後續的計算結果。

指令碼語言比如JS,它們一般都是擁有強大靈活度的解釋性語言,一般充當著“粘結劑”的角色。

等等還有諸多的語言分類,就不在此贅述了。

後話

由於這些都是我個人理解的一家之言,難免會有一些不當之處,歡迎園友們來交流探討。

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.