Please enable JavaScript.
Coggle requires JavaScript to display documents.
第一章 (實作方法 (Compilation (編譯) (編譯階段 (Lexical analysis (語彙分析) (字元轉換成詞彙單位,…
第一章
實作方法
Compilation (編譯)
說明
轉換很慢,但執行很快
將高階程式翻譯成機器碼
編譯階段
Lexical analysis (語彙分析)
字元轉換成詞彙單位
詞彙單位 : 識別字、特殊字、運算元、標點符號
Syntax analysis (語法分析)
把詞彙單元轉換成
parse trees
(代表程式的語法結構)
Semantics analysis (語意分析)
生成中間代碼(看起來像組合語言、用來檢查型別...等錯誤)
Code generation
生成機器碼
編譯過程
優化程式,使他們更小更快(通常在中間代碼)
Symbol table : 在編譯過程中充當一個資料庫
(背1-33圖片) :fire::fire::fire:
其他術語
system codes
在用戶程式可以被執行之前,必須先找到系統程式,並將之與客戶程式連結
由編譯器產生的機器語言必須與system code一起執行
Load module
(executable image)
the user and system code together
載入模組、可執行映像
連結與載入
收集系統程式,並使用linker將他們連結到使用者程式的過程
Von Neumann 瓶頸
記憶體
與
處理器
之間的連接速度決定了電腦的速度
執行程式指令通常比連接程式指令快 ->
連接速度
是為bottleneck
馮紐曼瓶頸為影響計算機速度的主要原因
(背1-31圖片) :fire::fire::fire:
Hybrid Implementation Systems(混合實作系統)
說明
編譯器與直譯器的折衷
特點
高階語言可以被翻譯成intermediate language,如此一來更容易被直譯
速度比純直譯還要快
例子
Perl : 程式先被部分編譯,可在直譯前檢查出錯誤
Java
byte code
Java Virtual Machine
替所有具有Java Virtual Machine ( byte code直譯器 + run-time system) 的機器提供可攜性
java的intermediate form
java的初始實作就是hybrid
(背1-39圖片) :fire::fire::fire:
Pure Interpretation(純解譯or直譯)
說明
程式由另一個程式來翻譯(類似口譯員)
特點
沒有翻譯(不用像compile一樣要先轉成機器碼)
容易實作(run-time error 可以立即被顯示出來)
執行速度慢
Statement的解碼是瓶頸
通常需要更多的記憶體空間
在高階語言中很少見
在Web腳本語言當中回饋顯著(e.g., JavaScript and PHP)
(背1-37圖片) :fire::fire::fire:
Preprocessors (前置處理器)
用途
前置處理器會在程式被編譯去展開嵌入前置處理器指令前立即處理程式
前處理器通常是用來指定要被include的程式碼來自哪個檔案
目的
將源碼中不符合語言規範的部分轉換成合法的形式
別名
又被稱為前編譯器(pre- compiler)或前翻譯器 (pretranslator)
JIT
Just-in-Time實作系統
一開始就把程式翻譯成中間語言
在執行期間,當中間語言方法被呼叫時,系統將之
編譯
成機器碼(機器碼版本保留到後續呼叫)
JIT系統被廣泛應用於java程式(.NET 語言也是用JIT實作的)
Just-in-Time (Java)
傳統 (慢)
將一道bytecode 的指令翻譯成機器碼之後,馬上執行這些機器碼,執行完這批機器碼之後,就把這些機器碼丟了,接著再翻譯下一道bytecode 的指令,繼續下去...。
下次要用時要重翻,效率不好
JIT 編譯器 (快)
會把常常執行的部分在第一次先翻譯好放在記憶體,以後再次執行到這裡時,就不用再翻譯,直接從記憶體取出機器碼即可執行。這
若記憶體夠大,JIT 編譯器的技術夠好,你的Java bytecode 執行速度也可以逼近純編譯式的程式。
編譯
程式被翻譯成機器語言
編程領域(應用領域)
科學
商業
COBOL (Common Business Oriented Language)
電子表格系統、資料庫系統
人工智慧
使用符號,而非數字來進行計算
使用limked list比 array方便
Function language: LISP appeared in 1959
Logic programming: Prolog
系統程式
Unix operating system: C
階層
應用程式->系統程式->硬體
網頁軟體
Markup languages : XHTML
Scripting language : JavaScript、PHP
General-purpose language : Java
語言評估標準
Readability (易讀性)
Overall simplicity(整體單純度)
Few feature multiplicity
例子 : "count++" = "count += 1 " ,寫++可能有人看不懂 -> 可讀性差
一個功能的寫法越少越好
你不容易記住,因此容易看錯、誤用或寫錯
Minimal operator overloading : 一個op所代表的意義越少越好
Orthogonality (正交性)
用越少的指令集合,做到越多相同的事情
控制語句
控制結構的存在 (e.g. while statement)
資料型態與結構
是否擁有充足的設備來定義資料結構 (e.g 沒布林的話就只能用1來代替true -> 不好讀)
語法注意事項
識別字(變數、函示...的名稱)的形式要可以靈活地組合(e.g 命名字數的限制影響變數名稱的清晰度)
擁有特殊字詞或方法來進行複合陳述 (e.g.
end if
、
end loop
)
自我描述結構、有意義的關鍵字 (r.g. UNIX的
grep
指令可以用來搜尋文字、檔案)
意義 : 一個程式語言寫出來的語句是否容易閱讀
Writability (易寫性)
簡單與正交
太多的正交性可能損害易寫性(compiler無法提早發現一些不合法的error)
越少的結構,越少的原語,用很少的規則結合他們
支持抽象化
能夠使用複雜的結構或運算元(e.g函數),且細節可被忽略
Expressivity (表達性)
可方便的使用特定運算元 (e.g count = count +1 -> count++)
意義 : 程式語言是否很容易撰寫
Reliability (可靠性)
型別檢查、例外處理
Aliasing
(別名 or 替身)
有多種不同的參考方法來讀取相同的記憶體位址
易讀與易寫性
語言若不支持自然的表達方式,演算法也就必定使用"不自然"的方法(可靠度 ↓)
意義 : 不易讓使用者犯錯,而犯錯也可以很容易的找出來
Cost (成本)
意義 : 最終所需的總成本
人力、編寫、編譯、執行程式、語言實作系統、維護
其他
Portability (可攜性) : 可以使用在各種不同的軟硬體平台上
Generality (通用性) : 適用於廣泛的應用
Well-definedness : 語言的官方定義是否完整與精確
語言類別
命令型
透過變數、賦值語句和迭代來執行工作
C, Pascal
函數型
給予參數,運算由函數呼叫指令所構成
LISP, Scheme
邏輯型
根據規則下去進行推論(而這些規則沒有指定順序或控制流程),為人工智慧的高階語言
Prolog
物件導向型語言
資料抽象化、繼承、late binding
Java, C++
Markup
用於具體指定網頁文件資訊的設計
XHTML, XML
編程環境
UNIX
古老的作業系統與工具集合
如今較常透過在UNIX之上運行的GUI進行運作
Microsoft Visual Studio.NET
龐大、複雜的虛擬環境
用來寫C#, Visual BASIC.NET, Jscript, J#, or C++
Borland Jbuilder and Eclipse
Java的集成開發環境
定義 : 開發軟體的工具集合
語言設計的權衡
可靠度 v.s 執行成本
java會檢查陣列的索引值,但這會導致執行成本增加
可讀性 v.s 易寫性
APL有很多強大的運算元,但卻導致較差的可讀性
易寫性 v.s 可靠性
C++指標很強大、且有彈性,但容易爆炸
語言設計如何被影響
電腦架構
語言是根據最普遍的電腦架構所發產出來的(e.g馮紐曼架構)
馮紐曼架構
說明
資料、程式被儲存在記憶體當中
記憶體與CPU分離
指令與資料由記憶體被傳到CPU中
(背1-23圖片) :fire::fire::fire:
如何執行機器碼
Fetch-execute cycle
程式計數器 : 儲存下一個要被執行的指令位址的暫存器
範例
initialize the program counter
repeat
forever
fetch
the instruction pointed by the counter
increment the counter
decode
the instruction
execute
the instruction
end repeat
編程方法
新的方法(e.g 物件導向),發展出新的程式語言
歷史 (效率 -> 結構化 -> 抽象化 -> 物件導向)
1950
簡單的應用、擔心機器的效率
1960
注重人的效率、可讀性、控制結構
-> 結構化程式設計
-> 由上而下的設計、逐步改進
1970
程序導向->資料導向
->資料抽象化
1980
物件導向程式設計
-> 資料抽象化+繼承+多型