【正文】
emp) a2所指單元 的內(nèi)容置為 temp的 值 (1)swap(x,y) (2)int *x,*y。 (3){ int temp。 (4) temp=*x。 *x=*y。 *y=temp。 (5)} (6)main( ) (7){ int a=1,b=2。 (8) swap(amp。a,amp。b)。 (9) printf(“a is now %d,b is now %d\n”,a,b)。 (10)} 在一個值調(diào)用過程中使用指針的 C程序 在 C程序中無傳地址所以用指針實現(xiàn)。 過程調(diào)用的四元式序列 S ? call id(arglist) arglist ? arglist,E arglist ? E par T1 par T2 par Tn call id,n 過程作為參數(shù)傳遞 三種環(huán)境:詞法環(huán)境 傳遞環(huán)境 活動環(huán)境 ? (1)program param(input,output)。 ? (2)procedure b(function h(n:integer):integer)。 ? (3) begin writeln(h(2)) end。 ? (4)procedure c。 ? (5) var m:integer。 ? (6) function f(n:integer):integr。 ? (7) begin f:=m+n end{f}。 ? (8)begin m := 0。 b(f) end {c}。 ? (9)begin ? (10) c ? (11)end 嵌套過程作為參數(shù)傳遞 p a r a m c 存取鏈 m b f . 存取鏈 連同存取鏈一起 傳遞過程實參 堆式動態(tài)存儲分配 ? 需求: – 一個程序語言允許用戶自由地申請數(shù)據(jù)空間和退還數(shù)據(jù)空間,或者不僅有過程而且有進程( process)的程序結(jié)構(gòu), ? 操作: – 堆提供兩個操作,分配操作和釋放操作 ? 情況 : – 經(jīng)一段運行時間之后,這個大空間就必定被分劃成許多塊塊,有些占用,有些無用(空閑) 碎片問題 程序語言允許用戶自由地申請數(shù)據(jù)空間和退還數(shù)據(jù)空間 ? C++語言中 new操作符施加在一個類型標識符上 ( 包括類名 ) ? Pascal語言中 , 標準過程 new能夠動態(tài)建立存儲空間并相應(yīng)地置上指針 。 標準過程 dispose是釋放空間 .new與 dispose不斷改變著堆存儲器的使用情況 。 ? C語言中有這些操作的若干個版本 , 但最基本的是 malloc和 free, 它們都是標準庫 ( stdlib)的一部分 面向?qū)ο蟮恼Z言的動態(tài)存儲 面向?qū)ο蟮恼Z言在運行時環(huán)境中要求特殊的機制以完成其增添的特性:對象 、 方法 、繼承以及動態(tài)綁定 。 面向?qū)ο笳Z言在對運行時方面的要求差異很大 。 Smalltalk與 LISP相似是完全堆式環(huán)境 C++則保持 C的基于棧的環(huán)境 實現(xiàn)對象 實現(xiàn)對象的一個簡單機制是,初始化代碼將所有當前的繼承特征(屬性和方法)直接地復制到記錄結(jié)構(gòu)中(將方法當作代碼指針)。但這樣做極浪費空間。 另外一種方法是在執(zhí)行時將類結(jié)構(gòu)的一個完整的描述保存在每個類的存儲中,并由超類指針維護繼承性(有時這也稱作繼承圖( inheritance graph))。每個對象保持一個指向其定義類的指針,作為一個附加的域和它的實例變量放在一起,通過這個類就可找到所有(局部和繼承的)的方法。此時,只記錄一次方法指針(在類結(jié)構(gòu)中),而且對于每個對象并不將其復制到存儲器中。由于是通過類繼承的搜索方法的,所以該機制還實現(xiàn)繼承性與動態(tài)聯(lián)編。其缺點在于:雖然實例變量具有可預測的偏移量(正如在標準環(huán)境中的局部變量一樣),方法卻沒有,而且它們必須由帶有查詢功能的符號表結(jié)構(gòu)中的名字維護。這是對于諸如Smalltalk的高度動態(tài)語言的合理的結(jié)構(gòu),因為類結(jié)構(gòu)可以在執(zhí)行中改變。 折衷方法 將整個類結(jié)構(gòu)保存在存儲中 , 計算出每個類的可用方法的代碼指針列表 (稱為方法索引表 , 如 :C++的 virtual function table) 。 它的優(yōu)點在于:可做出安排以使每個方法都有一個可預測的偏移量 , 而且也不再需要用一系列表查詢遍歷類的層次結(jié)構(gòu) 。 現(xiàn)在每個對象不僅包括實例變量還包括了一個相應(yīng)的方法索引表的指針而不是類結(jié)構(gòu)的指針 ( 當然 , 這個指針的位置必須也有可預測的偏移量 ) 。 class A { int m1。 void f1(){…} } class B extends A {void f2(){…} } class C entends B {void f2(){…} } class D extends C{bool m2。 void f1(){…}} class A a。 class B b。 class C c。 class D d1,d2。 m1 m1 m2 對象 c 對象 d1 對象 d2 m1 m2 m1 對象 b m1 對象 a A_f1 類 A B_f2 A_f1 類 B C_f2 A_f1 類 C C_f2 D_f1 類 D 某個單繼承 OO語 言的對象存儲示意 某個 OO語 言的程序例子 string day。 class Fruit { int price。 string name。 void init(int p,string s){price=p。 name=s。} void print(){ Print(On ,day, the price of ,name, is ,price,\n)。} } class Apple extends Fruit { string color。 void setcolor(string c){color=c。} void print(){ Print(On ,day, the price of ,color, ,name, is , price,\n)。} } void foo() { class Apple a。 a=New (Apple)。 (100,apple)。 (red)。 day=Tuesday。 ()。 } 它 的運行時存儲組織 臨時變量 局部變量 控制鏈 (EBP) 返回地址 (EIP) 實參 …… Apple的實例 …… …… Vtable of Fruit Vtable of Apple …… vtable int price(100) string name string color …… …… 棧區(qū) 堆區(qū)