轉載地址:http://computer.eefocus.com/lingyue/blog/09-03/167608_03695.html
許多初學者都會對這三個概念區分不清,應該說這三個概念是完全不同的,不能混為一談。在本文中,我就盡我最大的能力來講講這三個概念以及他們之間的關係。
首先說程式設計語言,它同人類的自然語言一樣也是一個語言,並且它是自然語言的一個子集。大家都知道自然語言是極其龐大和複雜的系統,具有很多不不確定性和不精確性,因此至今我們也沒有辦法對自然語言進行形式化的描述。程式設計語言只是自然語言的一個很小的子集,在電腦系統中,一切都是需要確定性和精確性的描述,因此程式設計語言也是極為規範的,在程式設計語言中,幾乎就不允許存在不確定性和不精確性,也就是說不能存在文法的二義性。這樣一個程式設計語言就可以通過一系列的產生式來進行形式化的描述,這一系列的產生式就被稱為文法,語言就是由文法來定義的。從另外一個角度來說,一個程式設計語言,它僅僅是一個語言,它只對程式進行形式上的要求。或者說,程式設計語言對應於編程中的編碼階段。我們有必要對程式開發的三個階段進行瞭解,程式開發從時間先後順序上可以分為三個階段:1.編碼階段,2.編譯階段,3.運行階段。在編碼階段,我們使用的就是程式設計語言。語言除了定義了文法以外,其他的任何事情他都不做。當然一種語言也有很多種版本,比如
BASIC 語言,就有很多種版本,C語言也是如此。這裡所講的語言的版本與編譯器的版本是不一樣的。C語言的標準版本就是 ANSI C,如果初學者會提出這樣的問題“C語言哪個更好?”,這樣的問題反映出他們對語言與編譯器之間的關係的認識的不足。如果從語言的角度來講 VC 和 TC 是沒有多大區別的,他們基本上都能支援 ANSI C。
再來看看編譯器。編譯器與語言的關係就是,翻譯者與語言的關係。編譯器就是一個翻譯,他把使用某種語言書寫的來源程式,翻譯成為等價的使用目標語言書寫的目標程式。前面我們也說了,語言是一個抽象的概念,是由文法來定義的。唯一實在的東西,也就是定義語言的文法。在使用語言時,我們只能說,使用這種語言去書寫一段程式。編譯器則是能夠將某種語言的來源程式進行翻譯,然後產生目標程式。我們通常會說,某個編譯器支援了什麼語言,也就是說這個編譯器能識別並翻譯這種語言。現在的C編譯器,一般都是支援了 ANSI C 語言的,另外,編譯器的設計者可能還會對
ANSI C 進行一定的擴充,而且各個編譯器進行擴充功能都是不同的,因此可能就會出現一個編譯器誕生以後,就會出現一個新的語言的現象。TC 和 VC 就分別對 ANSI C 進行了不同的擴充,比如在 TC 中有 far 等關鍵字,ANSI C 中是沒有的,在 VC 中有內嵌彙編的文法 _asm,而在 TC 中則是使用 asm 關鍵字,這些內容在 ANSI C 中沒有的。編譯器的輸入時來源程式,而其輸出則是目標程式。一般情況下,來源程式是使用某種進階語言書寫的,而目標程式則是某個特定機器的機器語言程式。另一方面,編譯器除了提供編譯功能,還會提供一些運行庫。所謂運行庫就是由一些事先寫好的子程式所組成的子程式庫。例如C語言中的
printf 函數,就是由C的運行庫提供的。在 ANSI C 中定義了一些C語言的標準庫函數,這些庫函數是標準C必須具備的,也可以說這些庫函數成為了 ANSI C 的一個部分。另外,不同的編譯器還可以提供自己的,非標準的庫給使用者使用,在 TC 中的 Graphics 庫,其實就是由 TC 提供的,它不是屬於 ANSI C 的。簡單的說,編譯器是由編譯器和運行庫組成的。在程式的編譯階段,就是使用編譯器對來源程式進行編譯產生目標程式。
在程式的運行階段則是在一個特定的平台上,由這個平台來執行編譯產生的程式。JAVA 虛擬機器是一個平台,DOS 和 Windows 也是平台,編譯器的作用就是溝通來源程式和程式的運行平台。來源程式相對於一個運行平台來說是不可識別的,但當編譯器將來源程式編譯成為這個平台所能夠識別的目標語言以後,程式就可以在這個平台上運行了。
應該看到,編譯器在其中起到了很重要的作用。我們現在可以明確一些概念了,程式設計語言只是語言,它本身很難說有什麼好壞,這就如同說“漢語和英語哪個好”一樣。使用某一種程式設計語言,我們可以書寫自己的程式,從而向電腦表達自己希望完成的功能。這個階段,我們稱為編碼階段。編譯器由編譯器和運行庫組成,編譯器負責將來源程式翻譯成為目標程式,運行庫提供了一些基本的子程式給程式編寫者使用。我們可以說編譯器是否支援某種語言,例如 TC 編譯器是支援 ANSI C 的,而 GCC 則是一個能夠支援多種語言的編譯器。然而不同的編譯器除了提供對某種語言的支援以外,還可能對該語言進行了某些功能擴充。編譯器在對語言的支援上,差別都是不太大的,這是因為許多語言都制定了一個標準,例如
ANSI C。編譯器的另外一個重要特性,就是對運行平台的支援。平台指的是一個程式運行所需要的所有軟體和硬體的基礎。編譯器對運行平台的支援,是通過將來源程式編譯成為目標程式,以及編譯器所提供的運行庫來實現的。例如,TC只能將C來源程式編譯產生,使用 80x86 CPU,作業系統為 DOS 的 16bit DOS 程式。VC只能將C來源程式編譯產生 80x86 CPU、作業系統為 Windows 的 32bit Windows 程式。使用編譯器對來源程式進行編譯被稱為編譯階段,這個階段編譯器將來源程式編譯為某個平台的目標代碼。程式在具體的平台上運行時,被稱為運行階段。應該指出,在編碼階段使用到的是程式設計語言,以及編譯器所提供的庫函數,這個階段產生的是來源程式。在編譯階段使用的是來源程式和編譯器,這個階段產生的是目標程式。在運行階段使用到的是目標程式和運行平台,這個時候產生的是程式運行結果。
因此說討論一個程式設計語言好壞沒有多大意義,因為他們使用的場合不同,比如組合語言和 Java 語言,要談論這兩個語言的好壞是沒有實際意義的。而說“C語言哪個好”之類的話也是沒有意義的,我想大家學的C也就是在 ANSI C 基礎上的C,並且不同的C語言之間的差別是極小的。我們通常指的 TC、VC 都是指編譯器,而不是語言。編譯器能夠支援一種或者多種的程式設計語言,TC 能夠支援 ANSI C,VC 能夠支援 ANSI C 和 ANSI C++,而 GCC 則是一個支援多語言的編譯器。如果真要說 VC 比 TC
好,只能說 VC 編譯器提供的庫函數更多,並且 VC 能夠支援的平台是 Windows,而 VC 編譯出來的代碼也都是 32bit 的。
在以上概念中糾纏了這麼久,我也不再想多說了。再來看開發環境。為了能夠方便程式設計者進行編碼、調試等工作,編譯器製造商在製作好一個編譯器以後,都會提供一個整合式開發環境(又稱為IDE)。在這個 IDE 中,使用者可以完成編碼、編譯、調試、啟動並執行全部工作。並且在最新的IDE中,可能還會提供一個可視化的設計功能,可以方便使用者進行程式介面的設計。例如 VB 等。另外一個方面,開發環境除了包括 IDE 以外,還包括了程式啟動並執行平台。比如硬體是 IBM PC 相容機,作業系統是 Windows 等。
可能,能講的也就這麼多了,感覺講的並不是很好,不過我已經儘力了。有些東西是很難說清楚的,“只能意會不可言傳”指的就是這個了。不要怪我講的不好,還是自己用心去理解和體會吧。