程式設計簡介
- 程式是什麼?
- 程式的英文是program,一般翻譯為計畫。其實計畫才是比較好的翻譯,程式一詞讓人丈二金剛模不到頭,不知所云。程式就是命令電腦做事的事先計畫。無論你要電腦做任何事,都必須事先做好程式設計,然後把程式輸入電腦,讓電腦執行。電腦會完全按照你的計畫執行你要電腦做的事。如果你程式寫錯了(稱為bug),電腦會照單全收,按照錯誤的程式執行,當然執行出錯誤的,你意想不到的結果。換句話說,電腦是完全不會判斷程式是否正確,程式的正確與否完全落在程式設計者身上。因此程式設計者必須對程式負完全的責任,不能推托的。
- 程式能做什麼及不能做什麼
-
- 程式能做程式設計者想做的事,程式不能做程式設計者不想做的事:如前所述,電腦對程式照單全收,不會違反程式設計者的意願。
- 程式能做電腦能做的事,程式不能做電腦不能做的事:電腦有固定的能力的,電腦無法做出它做不到的事情。至於電腦能做哪些事,看下節所述。
- 程式能做物理限制以內的事,程式不能做物理限制以外的事:每部電腦系統都有其物理限制,如處理器速度,記憶體容量等。超過物理限制的事,如時間或記憶體不足,程式寫的再好,都無法達到目的。在做程式設計以前,得把物理限制考慮進去,不要叫電腦完成超出其物理限制的事。
- 程式能做程式設計者能理解的事,程式不能做程式設計者不能理解的事:如前所述,程式設計得靠人,只有人也就是程式設計者能理解的東西,才有辦法寫出程式來。連人都無法理解的事,是無法寫出程式讓電腦執行的。
- 電腦能做什麼
-
- 輸入及輸出:電腦要跟外面溝通,就必須使用輸出入裝置。電腦要接收資料及呈現資訊,也必須使用輸出入裝置。電腦要控制機器,也必須使用輸出入裝置。如遙控器車的電腦,必須使用輸入裝置接收操作者的指令,及輸出裝置控制馬達的轉速和汽車行進的方向。
- 儲存程式及資料:電腦要執行程式以前,得先把程式儲存在電腦裡面,才能讓電腦執行。程式所要處理的資料,也得儲存在電腦裡面。
- 處理:程式就是事先計畫好的一堆指令,能夠處理某些特定的資料。每部電腦系統都有處理器,處理器的功能就是執行指令。指令包含拷貝(copy),計算(calculate),比較(compare),控制(control)。這些指令,下節再介紹。
- 網路通訊:網路通訊也算是輸出入的一部分。只不過,網路通訊的對象是另一部電腦,而輸出入的對象是被動設備。現在的大電腦都是用網路通訊設備連接小電腦構成的。因此網路通訊設備在現代電腦佔非常重要的位置。
- 程式語言的階級
-
- 機器語言(machine language):機器語言是由電腦指令構成的。嚴格說來,機器語言不算程式語言,因為沒有程式設計是撰寫機器語言的。由於電腦使用的是二進位,所以電腦指令是由一堆01的信號所構成的。指令包含拷貝(copy,將資料從其他裝置拷貝到處理器或從處理器拷貝到其他裝置),計算(calculate,四則運算加減乘除,邏輯運算且-and或-or否-not,位移-shift旋轉-rotate),比較(compare,等於=大於>於<,邏輯比較-and),控制(control,分支-branch,副常式-subroutine,陷阱-trap,例外-exception,中斷-interrupt,系統呼叫-system call)。
- 組合語言(assembly language):由於電腦指令是由一堆01的信號所構成的,非常難記,所以發明助憶碼(mnemonic)幫助程式設計者記憶指令。電腦指令和助憶碼是一對一的函數關係,所以組合語言可以發揮電腦的全部功能並且執行速度最快。缺點是,組合語言程式很難設計,而且組合語言是不可移植的(not portable)。換句話說,換了一種指令集架構(instruction set architecture),組合語言程式得全部重寫。因此,除了追求程式執行速度的極限,或者無法用高階語言撰寫的程式,一般不會需要寫組合語言程式。
- 高階語言(high-level language):高階語言就是以更接近人類思考來設計程式的電腦語言。最早出現的高階語言是FORTRAN(1957),之後雨後春筍了出現了如Lisp(1958),COBOL(1959),ALGOL(1960),BASIC(1964),Pascal(1970),Prolog(1972),Smalltalk(1972),C(1973),SQL(1974),Ada(1980),C++(1983),Objective C(1986),Object Pascal(1986),Perl(1987),Python(1991),Visual Basic(1991),Java(1995),JavaScript(1995),PHP(1995),Ruby(1995),C#(2001)等不計其數的高階語言。但是電腦無法執行高階語言,得翻譯成機器語言來執行。通常一行高階語言程式碼會翻譯成數個到數千個甚至數萬個電腦指令。如果一行程式碼翻譯的電腦指令的數量愈多,我們就說該高階語言愈高階。由於電腦的執行速度愈快,程式語言有愈來愈高階的傾向。
- 程式語言的種類
-
- 命令式(imperative)或宣告式(declarative):命令式語言是程式設計者必需清楚指示電腦完成事情所需的所有步驟,宣告式語言是程式設計者只需要指示電腦要事物之間的邏輯依存關係。由於一般機器語言是命令式的,所以以前命令式語言佔大多數,隨著電腦速度的提升,宣告式語言愈來愈多而且愈來愈重要。這是因為宣告式語言比較好寫,但是執行速度比較慢。
- 編譯式(compile)或解譯式(interpret):其實並沒有哪種語言是屬於編譯式或解譯式的,端看程式語言的實作(implementation)。某些語言多是編譯式的(如Java),而某些語言式屬於解譯式的(如PHP),但是常常很難區別。所謂編譯,就是將原始程式(source)在執行以前翻譯成機器語言,然後再由電腦執行,所以速度通常較快。所謂解譯,就是將原始程式在執行時由電腦解釋原始程式的意義,加以執行,所以速度通常較慢。不過愈來愈多的語言實作使用兩段式方法,先編譯成中間碼(intermediate),再交由電腦解譯中間碼。甚至中間碼用JIT編譯器(just in time compiler)編譯成機器語言的也愈來愈多。總之程式的實作方法五花八門,愈來愈多樣化。
- 型別(typed)或無型別(typeless):所謂的無型別這名稱並不好,應該說是單一型別,或多型別的程式語言。常見的型別有下列幾種:
- 基本型別(primitive type):
- 資料(data):布林(boolean,即真-true或偽-false),字元(character,即字母或數字或中文字或符號),數字(number,即整數-integer有號-signed或無號-unsigned,浮點數-floating point)。
- 副程式(subroutine):程序(procedure),函數(function)
- 指標(pointer):儲存資料或副程式或物件的位址。
- 複合型別(composite type):
- 字串(string):由一連串的字元所組成,如's'為字元,"string"為字串。
- 陣列(array):由一連串的物件所組成,並且用整數甚至其他物件當索引(index),如array為一陣列,array[1]代表第1個元素(element)。
- 串列(list):由一連串的物件所組成,串列只能從目前的元素指到後一個或前一個元素。串列即利用這種方法,從第一個元素指到最後一個元素,或最後一個元素指到第一個元素。
- 類別(class):以上三種都算是類別的一種,類別由一些物件所組成。每個物件包含了資料,稱為屬性(attribute)和處理資料的指令,稱為方法(method)緊密結合,這些屬性只能用這些方法來處理。譬如串列只能有下列方法,判斷是否為空串列,獲取第一個元素,獲取除第一元素剩下的串列,插入一個元素到第n個元素等。
- 資料(data)和指令(instruction)的關係:一般書籍把程式語言分成物件導向和非物件導向兩類。其實資料和指令的關係可分成四類:
- 資料和指令分開:以FORTRAN為代表,資料和處理資料的指令(運算式和敘述)分的很清楚,程式設計者完全清楚哪些是資料,哪些是指令。
- 指令也是資料:以Lisp為代表,指令包含程式的全部都是資料。
- 資料也是指令:以Forth為代表,指令包含資料及編譯都有執行的語意。
- 資料和指令緊密結合:以Smalltalk為代表,一般稱為物件導向(object oriented)。某些資料只能使用某些指令處理,資料和指令緊密結成了物件。
其實絕大部分的語言不屬於其中之一,都是介於之間,有其中四種分類的某些特性。尤其物件導向是趨勢,FORTRAN,Lisp,Forth的現代版本都有物件導向的特性。