將抽象定義成一種過程java
名字 映射到複雜的程序片斷python
從用途與功能角度考慮c++
而非具體實現c#
控制抽象:執行良好定義的操做數組
數據抽象:表示數據緩存
局部變量:執行代碼語句相關的變量安全
參數:輸入數據結構
返回值:輸出閉包
將以上三個限制於子程序做用域內併發
子程序表明調用方執行操做:任務委託
參數化
傳遞參數:傳遞信息(控制子程序行爲),提供數據(值)
實參在調用時映射到形式參數
形參:子程序內局部變量 ?
返回值:函數
不返回:過程
大多數要求函數在使用前已有聲明
c沒有
聲明:編譯器能夠檢查調用與函數簽名是否一致
調用序列:調用先後,被調用先後
8.1回顧棧佈局
調用棧上分配空間問題
子程序被調用時,棧頂部分配一個新棧幀:活動記錄
包含:實參、返回值,簿記信息(返回地址,保存的寄存器),局部變量、臨時值
在任意給定時刻,棧指針寄存器保存最後一個已用位置,或第一個未用地址
幀指針保存棧頂幀內的一個地址
幀中對象訪問:相對幀指針位移尋址
對象大小編譯時未知,放在幀頂部大小可變區域,地址與內情向量保存在某個固定區域
不存在未知大小對象:幀中對象相對棧指針偏移量靜態可知,不用幀指針
參數大小編譯時未知:參數放在其餘參數下方大小可變區域,地址與內情向量放在相對幀指針的已知偏移量處
或調用方只傳遞臨時地址與內情向量,被調方複製實參到棧頂可變區域
圖
容許嵌套與靜態做用域的語言:
對象可能在外圍子程序中
維護靜態鏈,找到這些非局部非全局對象
棧幀包含一個 對詞法上外圍幀的引用——靜態鏈(指針)
爲子程序返回時恢復而保存的幀指針——動態鏈(指針)
一個活動的子程序,其外圍子程序是活動的
只有經過外圍子程序才能見到且調用內層子程序
嵌套定義的子程序,只能從外圍子程序進入。由於函數名對其餘函數不可見。
局部子程序:詞法靜態嵌套關係表示可見性
8.2調用序列:完成調用工做的實現
維護子程序調用棧
調用先後處理代碼,被調先後處理代碼
進入子程序的過程完成的工做
傳遞參數
保存返回地址
修改程序計數器
修改棧指針與分配空間!!
保存子程序可能修改的寄存器值(包括幀指針)
修改幀指針,指向新幀棧
執行新幀上的對象初始化代碼
離開時的工做
傳遞返回參數,返回值
局部變量終結代碼,釋放空間
釋放幀棧(恢復棧指針)
恢復保存的幀指針
全部工做中一部分只能由調用方完成(只有調用方知道的信息:傳遞參數,返回地址?靜態鏈)
其餘能夠共同完成
調用方作工做
被調方作工做:能夠節省空間,子程序不止一次被調用???
##調用樹圖
保存恢復寄存器
理想模式:調用方正在使用,而被調方用於其餘目的。則將之保存(寄存器集合的子集)
實際:調用方保存全部正在使用的寄存器 被調方保存全部將要修改的寄存器
寄存器分組:調用方保存有價值的一組 被調方改寫沒有價值的一組(可能存在語義一致的資源)
靜態鏈維護
一部分維護工做必須由調用方完成:調用方的詞法外層
調用方計算被調方的靜態鏈,做爲隱式參數傳遞
具體分兩種狀況:
1.被調方直接嵌套在內層
被調方靜態鏈引用調用方的棧幀。調用方傳遞幀指針
2.被調方在調用方外k層
調用方對靜態鏈作k次間接引用,傳遞給被調方
典型調用序列
調用方
保存寄存器
計算參數值,移入棧或寄存器
計算靜態鏈,做爲隱式參數傳遞
執行子程序調用指令,跳入子程序,返回地址放在棧,寄存器中
被調方
分配幀
保存原有幀值,賦予新值
保存寄存器
子程序結束
被調方
返回值移入寄存器或棧
恢復寄存器
恢復fp,sp
跳回返回地址
調用方
保存返回值
恢復寄存器
優化:
沒有局部變量
不須要幀棧,參數來自寄存器
區頭向量
取代靜態鏈的小數組,緩存地址計算結果。空間換時間
寄存器窗口滑動
內聯展開
增長了代碼量
保持語義(相對宏)
編譯器可瞭解語義,可優化
8.3參數傳遞
傳遞值,引用,閉包
規則惟一:c
規則不惟一:python?
8.3.1參數模式
值調用,傳遞副本。獲得值
引用調用:傳遞地址。形參爲實參的新名字,別名。
傳遞的必須是左值
引用傳遞爲了修改參數
值傳遞+返回值:形參賦值回實參
討論值模型與引用模型只對使用值模型的語言有意義
變量的引用模型,不必定要求全部對象經過地址訪問。java,python
java內部類型值模型,自定義爲引用模型
不管變量是值仍是引用,都經過複製來傳遞
與賦值語句語義一致
函數意圖
修改實參
保持實參
間接訪問的代價
複製對象的代價(大型值)
只讀參數:同時得到引用參數的效率與值參數的安全性
c:const聲明:加工時常量
const指針:保證不引用其餘對象 或 引用的對象不被修改
c++
引用參數&
不引用其餘對象 const 指針
引用做爲返回值
閉包做爲參數
閉包:子程序的引用,並帶有子程序引用環境
代碼地址+引用環境
帶環境的可調用對象
c:指向程序的指針
面向對象:模仿閉包行爲,閉包對象,單方法類
類是對象:有屬性(靜態方法,類變量)
類是類型:建立類實例對象,提供方法,實例屬性
8.3.3特殊目的的參數
類似數組:不一樣語言,數組維數與邊界的約束時間不一樣:編譯時,加工時,執行時
語言中,針對參數的規則 比 針對變量的規則 寬鬆
推遲到運行時肯定形狀的數組參數:類似數組參數,開放數組參數
默認參數
提供值:修改函數默認行爲
缺省實參:使用默認值,默認行爲
默認值爲:值,字面量,不可變
:對象,可變
命名參數:相對於位置參數:關鍵字參數:調用時的按名傳參行爲
混合使用:先位置參數
可變個數參數表
對靜態類型不安全,沒法靜態檢查(不知道個數,不可能檢查)
對動態類型安全?運行時檢查,動態檢查
類型安全的靜態類型:要求可變長參數表類型相同
8.3.4函數返回
不區分表達式與語句的語言:函數的值=函數體(自己是一個表達式)的值???
顯式return:反作用:函數中止
正交性:返回值類型限定
返回複合值,元組
正交性:弱化限制
設計限制了出現的對象必須知足的特徵:第一類,第二類,第三類 類型 靜態已知
8.4泛型子程序與模板
須要在不一樣類型對象上使用同一操做
OS:隊列:保存進程、存儲描述符、文件緩衝區、設備控制塊、等
隊列數據結構的特徵與數據項的特徵無關
8.4.1不一樣的實現方法
隱式參數多態性:參數類型無描述,但依然是類型安全的
類型檢查推遲到運行時
顯式多態的泛型機制
C++模板
用於建立容器
容器:數據抽象,保存一組對象。操做與對象類型無關(不要求提供接口,要求極少的接口)
泛型模塊(或類)須要泛型子程序,實現操做
泛型參數:
java c#只容許傳遞類型
ada c++容許傳遞常規類型的值?子程序或類?
泛型代碼:對類型參數的最低特性要求(最小接口)
適當的限制條件:顯示描述,或編譯器推斷
編譯器的工做是隱式的 寫於程序正文的是顯示的
不一樣的實現方法
Ada c++靜態機制:編譯時 建立使用泛型代碼的多個實例,每一個實例獨立代碼副本
C++:安排獨立的類型檢查
優化:共享代碼
類型檢查:要求特定的類型——函數簽名(運算符)
要求提供接口——泛型
java:一個泛型全部實例運行時共享代碼
標準基類object的實例(語義轉化爲子類多態性)
子類運行父方法
靜態泛型與宏 有共性
泛型 宏
內聯函數 宏
編譯器理解的 過後添加的,預處理器展開的
類型檢查
常規做用域規則
8.4.2泛型參數的約束條件
泛型也是種抽象:接口提供全部信息
Ada,java:限制泛型參數,顯示說明參數類型支持的操做
java:從父類繼承的接口實現
c++:摒棄顯示限制,提供參數檢查
參數類型不支持操做:靜態語義錯誤避免隱式使用泛型參數類型的操做
8.4.3隱式實例化(函數)
泛型函數看作重載(重載是否必定要求函數簽名不相同?須要聲明,須要強類型)
c++隱式實例化規則比 重載子程序 嚴格
編譯器不對子程序實參做類型強制
8.5異常
子程序調用棧的回退
難以在局部上下文處理
不妨礙正常的流程
錯誤處理移到主流以外
控制轉移
致命異常
可恢復異常
處理程序與異常的動態約束:容易形成語義模糊
靜態約束:詞法位置約束的代碼塊。做爲原始代碼塊相併存在的補充(if else)。
調用點引起異常,調用方(&調用方的調用方)處理
沿動態鏈返回,(依然存在動態約束,可是受限得多)
在調用方代碼塊(靜態約束)中尋找局部處理程序,檢查匹配,處理/從新拋出/終止並打印
沿動態鏈尋找調用方,在調用方代碼塊(靜態環境)尋找局部處理程序
匹配——處理
不匹配——從新引起(傳播)
8.5.1異常的定義
預約義異常
異常類型
參數:類的域(字典)
try
throw,raise主動引起
傳播(接收並重發)
catch
最終未處理的狀況
清理操做:相似調用序列語義(子集),可是未完成工做
離開做用域:內存釋放
final
with——exit?
8.5.3異常的實現
處理程序的連接表棧(解釋數據結構?)
控制進入保護區:處理程序加入表
爲實現沿動態鏈的反向傳播,對於中間層子程序無處理程序:隱式處理程序:子程序的後續代碼,從新引起異常
編譯時記錄表格:處理程序與受保護塊的對應關係(指針)
異常發生:程序計數器爲key,對錶格折半搜索
特別處理隱式處理程序:返回地址做爲key
獨立編譯:各個子程序獨立表格
無異常機制:模擬行爲
8.6協程
須要閉包,保持環境
繼續:常量,建立後不改變
協程:每次運行時變化:跳進時位置爲上次退出時位置
一組協程:同時存在的上下文,但每一個時刻只有一個在執行,主函數調用
用於離散時間的模擬
要求順序的完整性檢查,替代深層循環
控制權轉移
獨立的程序計數器
線程比協程好用
協程是併發的,不能共享棧
若是棧幀在堆中分配,能夠避免溢出與內部碎片問題???
但會增長子程序調用開銷
仙人掌棧
表示協程或進程:上下文塊
協程轉移
8.7事件
程序外部發生
時間不可預測
須要程序響應
等待輸入:同步,阻斷式
回調函數
處理程序:特定時間調用
異步設備活動
中斷機制
切換棧到回調函數
信息緩衝區
基於線程處理程序
事件:單獨控制進程