解釋性的程序和編譯性的程序的執行過程

計算機只能執行包含機器指令(也稱爲機器代碼)的程序,不能直接執行我們編寫的程序。用高級語言編寫的程序基本上有兩種執行方式,在大多數情況下,一種語言會選擇其中一種執行方式。例如,用BASIC語言編寫的程序通常是解釋性的,也就是說另一個稱爲解釋器的程序會檢查BASIC源代碼,確定該程序要做什麼,再讓計算機完成這些動作。
而C++是一種編譯語言。在執行C++語言之前,必須用另一個程序(即編譯器)把它轉換爲機器語言。編譯器會檢查C++程序,並生成機器指令,以執行源代碼指定的動作
使用解釋性語言,執行過程是間接的,也就是說,每次執行程序是,都需要確定源代碼的意圖。因此,這種語言比編譯語言的對應程序的執行速度要慢的多,有事要慢100倍。

這個規則的例外是JAVA,由於JAVA主要用於不同計算機之間移植,以及用在Internet上,所以它基本上是一種解釋性的語言。儘管如此,還有一種just-in-time編譯器可以在執行過程中,爲JAVA源代碼生成對應的機器碼,從而大大提高了執行速度。


從C++源代碼中創建可以執行的程序模塊需要兩個過程。第一步是編譯器把每個.cpp文件轉換爲對象文件,其中包含了與源文件內容對應的機器碼。第二步是鏈接程序把編譯器生成的對象文件合併到包含完整可執行程序的文件中。

 編譯器把每個源文件看作一個獨立的實體,爲每個.cpp文件生成一個對象文件。然後在鏈接步驟中,把所有程序的對象文件和必要的庫函數(庫例程)組合起來,生成可執行文件。

源文件的編譯過程包含兩個階段,而它們之間的轉換是自動的。第一階段是預處理階段,在正式的編譯階段之前進行,預處理階段將根據已放置在文件中的預處理指令來修改源文件的內容#include指令就是一個預處理指令,它把頭文件的內容添加到.cpp文件中。

這個編譯前修改源文件的方式提供了很大的靈活性,以適應不同的計算機和操作系統的限制。一個環境需要的代碼和另一個環境需要的代碼可能有所不同,因爲可用的硬件或操作系統是不同的。在許多情況下,可以吧用於不同環境的代碼放在同一個文件中,再在預處理階段修改代碼,使之適應當前的環境。

編譯器爲給定的文件輸出的是機器代碼,執行這個過程需要較長時間。在對象文件之間並沒有建立任何連接。對應於某個源文件的對象文件包含有其它源文件中定義的函數引用或其他指定項的引用,而這些函數或項仍沒有被解析。同樣,也沒有建立同庫函數的鏈接。實際上,這些函數的代碼並不是文件的一部分。這些工作使用鏈接程序(有時也稱爲鏈接編輯器)完成的。


鏈接程序把所有對象文件中的機器碼組合在一起,並解析它們之間的交叉引用。它還集成了對象模塊所使用的庫函數的代碼。這是連接程序的一種簡化表示,因爲這裏假定在可執行模塊中,模塊之間的所有鏈接都是靜態建立的。實際上有些鏈接是動態的,即這些鏈接是在程序執行時建立的。

鏈接程序靜態地建立函數之間的鏈接,即在程序執行之前建立組成程序的源文件中所包含的函數鏈接。動態建立的函數之間的鏈接(在程序執行過程中建立的鏈接)將函數編譯並鏈接起來,創建另一種可執行模塊——動態鏈接庫或共享庫。動態鏈接庫中的函數鏈接是程序調用函數時才建立的,在程序調用之前,該鏈接是不存在的。

動態鏈接庫有幾個重要的優點。一個主要的優點是動態鏈接庫中的函數可以在幾個並行執行的程序之間共享,這將節省相同函數佔用的內存空間。另一個優點是在調用其中的函數之前是不會加載到內存中的。也就是說,如果不使用給定動態鏈接庫中的函數,該動態鏈接庫就不會佔用內存空間。動態鏈接庫是與操作系統緊密相關的一個系統功能。

 

 

2009-05-2520:14:45

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章