Transcript ******-PERL

程式語言與資料結構應用介紹
09910IPE100100
2010/12/09
陳昱廷
參考自原始作者:蔡英德教授
程式語言簡介
 我們需要使用較近於人類思維的語言(高階語言, high
level language), 藉由編譯器(compiler) 或直譯器
(interpreter)的轉換, 成為計算機了解的機器語言
(machine language), 如圖16.1。
語言在不同面向下之特性比較
 依階層與發展過程:
1.機器語言
2.組合語言
3.高階語言
 依使用模式:
1.直譯式程式語言
2.編譯式程式語言
 依應用:
1.一般用途
2.特殊用途
不同階層語言之特性比較
 發展過程:先有機器語言, 再有組合語言, 進而發展
出適合人類閱讀、學習的高階語言。
 執行速度:以機器語言最快, 組合語言次之, 高階語
言較慢。
 機器相關性:機器語言和組合語言受機器限制, 高階
語言不受機器限制。
 翻譯程式:組合語言和高階語言必須有翻譯程式, 而
機器語言不用翻譯即可執行。
程式語言之模式劃分
 1. 直譯式程式語言
 也稱為腳本語言(script language) ,此種語言程式系統可以將
原始程式的指令逐一的翻譯並執行, 不需要經過編譯, 如
BASIC、LOGO、HTML等。
 它的特點是修改程式及除錯, 較為簡單容易。
 2. 編譯式程式語言
 撰寫的原始程式, 需要經過編譯器編譯之後, 輸出為電腦中直
接執行的目的程式, 如C、C++、PASCAL...等。
 它的特點是再次使用只要執行目的程式, 無須重新在編譯其
原始程式。
程式語言之應用劃分
 1. 一般用途程式語言
 指用於一般範圍的通用程式語言。
 如BASIC、PASCAL、C, Java...等。
 2. 特殊用途的程式語言
 應用於特殊領域的程式語言。
 例如應用於商業的COBOL, 工程的FORTRAN, 網路的
HTML, Javascrript, 資料庫系統的SQL, 人工智慧領域的
程式語言如LISP, 網頁伺服程式端的PHP, 管理系統與處
理文字的Perl, 整合不同語言的Python..等。
程式語言結構與組成
 1.資料型態(data type)
 計算機藉由處理資料來求得我們所要的結果, 程式語言
的資料如何表示是一項很重要的主題。
 2. 指令及流程控制
 一旦資料被確定, 機器必須被告知如何對這些資料進行
處理。
 3. 副程式與函式
 副程式可重複使用, 以方便維謢,讓程式變得精簡與減
少程式錯誤。
資料型態(data type)
 程式中專門處理資料的系統被稱為程式語言的型態
系統(type system);對型態系統的研究和設計被稱
為型態理論(type theory)。
 計算機藉由處理資料來求得我們所要的結果, 程式語
言的資料如何表示是一項很重要的主題。
 程式語言中常見的資料型態:整數(integer)、浮點數
(floating-point)、字元(character)、陣列(array)、記
錄(record) 及指標(pointer) 型態。
資料型態(data type)
 整數型態:
 C語言最基本的整數資料型態是“int” , 一般系統以4個bytes來表示,
若要確定它的大小, 可用“sizeof( int) ” 求得。
 它的值域在4個bytes的情況下則為從–2,147,483,648 至
+2,147,483,647 之間。
 浮點數資料型態:浮點數型態是用來代表實數的, 它是以科學記號
的表示法來表示, 可以分為三部分:
 (1)符號(sign)部份:佔用1個bit, 表示該浮點數的正負符號。
 (2)精確度(fraction) 部份:佔用若干個bit, 表示科學記號的定點數部份。
 (3)指數(exponent) 部份:佔用若干個bit, 表示科學記號的次方部份。
 字符型態:通常以1個byte表示。
 其表示方法則是使用美國國家標準局所製定的ASCII碼。
 在C語言中, 字符宣告char亦可視為一種整數型態, 其範圍為從-128
至+127之間。
資料型態(data type):陣列型態
 •陣列為一群具有相同資料型態的變數所組成, 例如100個整數或
50個浮點數等。它可以有許多型式:一維陣列, 二維陣列等等。
 •例如:
 即宣告了A是由100個整數所組成的陣列(如圖16.2);而B是一個
30×40的二維陣列。
記錄型態
 記錄型態記錄型態有時又稱為結構(structure) 型態,
 它所存放的是異類型的資料型態, 是由一群欄位(field) 所
結合而成的, 而每個欄位都可以是不同的資料型態。
 記錄型態也可與陣列相結合, 以形成更複雜的資料結構。
 圖16.3是一個C語言中陣列型態與記錄型態相結合的範例。
 圖, 此宣告表示有100筆學生的資料,每一筆分別是結構型態,它除了存放學生
的學號外,另外也以score陣列來存放平時、期中考及期末考等3項成績。
 指標型態所存放的值是位址。
 它在很多語言都扮演重要的角色, 不僅可達到動態的資料結
構, 並且可以使記憶體的管理達到更有效的利用。
 藉由指標的特性, 加上動態的記憶體配置, 可以完成鏈結串列
(linked list)、樹狀結構(tree)、堆疊(stack)、佇列(queue) 等
資料結構。
 圖16.4是指標型態的一個範例
圖,變數p為一個整數型態的指標,其指向變數a所在的
依址,宣告時*p表示p為指標型態;&a則是指a的位址
指令及流程控制
 較簡單的指令可以使用關鍵字或定義好的語法結構
來完成。不同的語言利用序列系統來取得或組合這
些語句
 語言中的其他指令也可以用來控制處理的過程(例如
分支、迴圈等)
 流程控制(flow control) 決定了程式的執行方向。
流程控制:判斷結構(1)
流程控制:判斷結構(2)
流程控制:迴圈結構
副程式與函式
 當一個程式執行到一半時,停下來呼叫另一個子程式來執
行, 執完時, 再返回主程式中斷的地方, 然後繼續往下執行。
 這個被呼叫的程式被使用到的次數比較頻繁時, 我們可以
將這個程式建立成一個副程式。
 我們在主程式中利用call指令就可以呼叫它, 而不用一再重
複的重寫副程式的內容。
圖,函式呼叫與用法
使用副程式的好處
 1. 程序可重複使用, 以方便維謢與程式除錯。
 2. 程序可以讓其他方案或專案使用。
 3. 程序的邏輯簡單、明確, 可以讓程式變得精簡且可
讀性高。
 4. 程序具有模組化的功能, 讓不同的程式設計師分別
撰寫獨立不同功能的程序, 並以團隊開發, 加快應用
程式開發的時間。
副程式的引數傳遞方式
 1.呼叫程式後面所接的引數串列稱為實引數。
 2.被呼叫程式的程序所設定的引數串列稱為虛引數。
 3.呼叫與被呼叫之函式名稱必需相同, 但兩者的引數名稱
可以不相同。
 4.若程序的虛引數宣告為傳值呼叫, 則呼叫程式的實引數
與被呼叫程式的虛引數是佔用不同記憶體。
 5.呼叫程式的實引數與被呼叫程序的虛引數兩者佔用同一
位址的記憶體就是參考呼叫; 也就是說在做參數傳遞時,
呼叫程式中的實引數是將自己本身的記憶體位址傳給被
呼叫程式的虛引數。
 6.程式敘述可以再呼叫自已本身的程序, 我們稱為遞迴程
序(Recursive Procedure)。
語言、平台、程式庫
 1. 平台
 軟體系統、作業系統、硬體架構。
 2. 語言
 但不同編譯器對語言規範的在不同平台上解釋有所差
異。在針對不同系統進行構建之前, 程式就得加以考慮。
 3. 跨平台的程式庫
 為某個特定平台所開發的程式不一定能在別的平台上
重新編譯之後就能執行。為達到這個目的, 我們需要一
組跨系統平台的程式庫。
平台
 計算機系統最普及常見的作業系統大致有Windows、Linux 與
Solari、FreeBSD、Mac OS、Android 等。
 這些不同的作業系統大致皆可支援多種硬體架構(CPU) 例如Sun
Solaris 可支援x86 (INTEL, AMD, NVIDIA, VIA)、Sun Sparc…等等。
 支援多種作業系統的軟體有很多, 像是資料庫管理系統(DBM) 中的
MySQL系統和Oracle 系統;網站伺服器(Web server) 系統、應用程
式伺服器中的Apache 與Tomcat 網站伺服器, 這些系統大致都支援
不同的多種作業系統;也支援不同的多種作業系統如:Linux、
FreeBSD、Solaris、AIX、Windows等。
 這些跨軟體甚至是硬體架構平台之軟體系統之所以能夠在不同平
台通行無阻的主要原因是因為這些整個計算機系統當初在設計發
展時就運用了整組的跨平台架構的想法。
語言(跨平台)
 程式語言理論上是跨平台的, 但不同編譯器對語言規範的
解釋常有所差異。在針對不同系統進行構建之前, 程式的
撰寫就需加以考慮。
 如Java這樣的語言, 從一開始就意識到要在各個平台下運
行, 所以跨平台在其平台的本地語言環境中已經實現。
 Java 為了提供跨平台的用戶圖形介面GUI, 就利用了Swing
程式庫在許多平台下的實現。各種跨平台問題, 都需要各
自的本地庫來解決。
 一些開放原始檔軟體允許用戶自己來編譯目的碼(object
code), 以達較佳的跨平台效果。
跨平台的程式庫
 許多API (應用程式介面) 是與平台相關的。開發的程式不一定能在別的平
台上執行。
 跨系統平台的程式庫:一個程式庫針對各個主要平台萃取出一個共通的程
式庫, 就可以解決這個問題。如OpenGL因為不依賴於任何特定的作業系統、
CPU構架圖形設備, 可以看作是跨平台的。
 特定平台的API可以在其他系統上作為兼容層而新建, 例如WINE程式庫使
得Windows程式可以在UNIX系統上運行。
 許多程式語言還有跨平台的擴展以及中介元件, 這樣的原始碼, 只要進行一
點小修改, 就可以在不同平台下編譯/運行。
 網頁如果可以由任何瀏覽器正常瀏覽, 就可以被認為是跨平台的, 或者跨瀏
覽器的。這需要一些專業知識, 幫忙克服網路標準上的差異。
資料結構與演算法
 資料結構是指資料在電腦內的表示方式和存取方法。
 演算法就是電腦處理資料的詳細流程。
 資料結構與演算法要相互配合才能有效率的處理資
料。
 每個資料結構都有其對應的存取使用方法,演算法
設計必須搭配資料結構設計才能達到最佳表現。
虛擬碼
 「流程圖」(Flow Chart):用來描繪虛擬碼動作。
 流程圖是由一些圖形所組成,主要的圖形如下圖所示。
虛擬碼 – IF-THEN
 IF-THEN
 IF-THEN指令在選擇或決策使用。
 語法格式為:
虛擬碼
 範例:
虛擬碼
 範例:
虛擬碼 – FOR-LOOP
 FOR-LOOP
 此指令在需重複執行指令時
使用。
 語法格式為:
虛擬碼
 例如要重複印出五個A,利用FOR-LOOP寫出的虛擬碼如下:
虛擬碼 -- WHILE-LOOP
 WHILE-LOOP:
 此指令在需重複執行指令時使用
 可以把前面FOR-LOOP的例子改為WHILE-LOOP:
基礎資料結構 – 陣列(Array)
 當一個資料需儲存到主記憶體時,可以指定一個變數
來儲存,但若要同時處理100個同樣類型資料時,指定
100個不同變數名稱,在使用上就相當不便了,此時就
能利用陣列來處理。
 陣列是記憶體的變數名稱,它是一群具有相同性質的
資料型態之集合,而各個元素以不同的註標(Index) 值
來區分。
基礎資料結構
 一維(One Dimension) 陣列
 以n個註標來存取元素的陣列稱為n維陣列。
佇列與堆疊
 當我們買票看電影時,大家依據到達的先後次序排
隊買票,先來的先買票進場;但是當我們清洗餐盤
時,常是把洗完的盤子直接就放在之前洗好的盤子
的最上面,等到要取用盤子時會先拿最上面的盤子,
反而是後放上去的盤子先使用。
 前者排隊買票是「先進先出」(First In First Out,
FIFO) 的處理觀念,而後者使用盤子是「後進先出」
(Last In First Out,LIFO) 的處理觀念。接下來介紹的
佇列和堆疊分別應用了FIFO和LIFO的處理觀念。
佇列與堆疊
 ADD,
DELETE
 push, pop
樹與二元樹
下圖是一張具有樹狀結構的家譜
 「樹」(Tree)是一群有限個但至少一個
「節點」(Node)所成的集合,其中某
個節點被指定為樹根(Root)。
 除了樹根以外的節點可分為T1, ...,Tn等
n個不相交的集合(n≥0),而且每個集
合也是一棵樹。T1, ..., Tn稱為樹根的
「子樹」(Subtree)。
 若節點N沒有子樹,則稱節點N為「樹
葉」(Leaf)節點N的子樹的樹根稱為節
點N的「孩子」(Child),而N稱為其孩
子的「父母」(Parent)。
樹與二元樹
 二元樹(Binary Tree):
 是每個節點至多兩個孩子的樹(如下圖)。我們稱節點左
邊的孩子為左孩子,右邊的為右孩子。
樹與二元樹
 用右圖的LCHILD、
RCHILD 和DATA 三個欄
位表示節點。
 其中LCHILD和RCHILD
分別是節點的左孩子和
右孩子,DATA 是原來
的節點資料
樹與二元樹
 則可將圖:
改成
表示
樹與二元樹
 「追蹤」(Traversal)樹上的節點是對樹狀結構相當重要的運算。
 追蹤樹上的節點,就是拜訪每個節點恰好一次,而其追蹤的結果
就是拜訪節點的順序。
 追蹤方式可分:中序追蹤, 後序追蹤, 前序追蹤




以下將介紹二元樹的各種追蹤方式。
中序追蹤(Inorder Traversal):
若樹只有一個節點a,定義此樹之中序追蹤為a。
對二元樹的中序追蹤是先以中序追蹤拜訪樹根的左子樹,再拜訪
樹根,然後以中序追蹤拜訪樹根的右子樹。
 各子樹又依此定義遞迴(Recursive)追蹤下去。
演算法 -- 排序
 「排序問題」(Sorting Problem) 是將資料依據其
“大小"由小至大或由大至小排好,例如將考卷依分
數從高至低排好。
 氣泡排序法
氣泡排序法
 用氣泡排序法將這五個資
料由小到大排序好。
 首先要把最大者從左向右
推到到D[5]內。從D[1]開始,
讓兩個相鄰的資料相比,若
左方的資料比右方的大,就
將資料交換,也就是讓較大
者放到右方,而較小者放到
左方。
 先比較D[1]與D[2],因為
D[1]<D[2],所以資料不交換。
再比較D[2]與D[3],因為
D[2]>D[3],所以交換D[2]和
D[3]的資料。
 如此繼續向右比較下去。
最後在D[5]內的49就是這
五個資料的最大者。
D:
氣泡排序法
 找出最大數後,然後就要
找出次大數並放於D[4]
內。
 同樣的,從D[1]開始,讓兩
個相鄰的資料相比,把較
大者放到右方,而較小者
放到左方。
 最後在D[4]內的38就是
這五個資料的次大者。
D:
氣泡排序法
 右圖是浮現第三大數的
過程。
 相同的,利用前述的方法
可找出第三大數並放於
D[3] 。
 最後將30放於D[3]內。
D:
氣泡排序法
 最後就是找出第四大數
並放於D[2]內。
 之後陣列D的內容為13、
25、30、38、49,是由小
到大的順序。
D:
氣泡排序法
 下圖是一個氣泡排序演算法。
 5~18行的迴圈J用7~14行的迴圈I比較D[I]與D[I +1] 相鄰資
料,以使得第N + 1 –J大數放於D[J ] 中。
 9~11行是交換D[I]和D[I + 1]的內容。
 FLAG 變數用來表示迴圈I內是否有交換資料,若無資料交
換,代表資料都已經排序好了,可以停止排序。