Transcript 投影片 1

第七章
參數的傳遞
陳維魁 博士
[email protected]
儒林圖書公司
1
大綱








副程式概念介紹
副程式基本觀念
參數傳遞的方法
別名
超荷法
通用性函數
六種常見的副程式呼叫方式
精選習題
2
副程式概念介紹

副程式的元素


副程式的名稱
參數

實際參數(actual parameter)


呼叫副程式的參數串列即稱為實際參數,又稱為真
實參數。
型式參數(formal parameter)

被呼叫副程式的參數串列即稱為型式參數,又稱為
虛擬參數(dummy parameter)
3
副程式概念介紹

副程式的元素

環境(environment)


由副程式執行時所參考的全域變數(global
variable),區域變數(local variable)及其他必要的
資訊構成
副程式執行的程式段
4
範例

program demo;
var
a1,a2 : integer;
....
procedure swap(b1, b2:integer);
var
temp: integer;
begin
temp := b1;
b1 := b2;
b2 := temp
end;
begin
swap(a1, a2)
end.

左例中
swap(a1,a2)
的參數串列
(a1,a2)即為實
際參數串列,
副程式
swap(b1,b2)
中的參數串
列(b1,b2)則
為型式參數
串列
5
型式參數的語意模型

型式參數的三種不同語意模型分別為

in mode


out mode


型式參數可從對應的實際參數接收訊息。
型式參數可將訊息傳給對應的實際參數
in out mode

型式參數可從對應的實際參數接收訊息也可將訊
息傳給對應的實際參數
6
實際與型式參數的對應關係

關鍵字對應法



參數的個數較多時適用
當參數的數目很多時,採用關鍵字對應法,程
式的可讀性較高、較易維護不易出錯且可以不
必按照特定順序
位置對應法

參數的個數較少時適用(通常是5個以下)
7
副程式的執行模式




副程式的執行動作是因為呼叫程式呼叫了
副程式所引起
當呼叫程式呼叫副程式時會將程式的控制
流程轉移到副程式開始處
待副程式執行結束時會將程式的控制流程
轉移到呼叫程式中呼叫副程式敘述的下一
個敘述
副程式執行時可改變其所處的環境的狀態
8
副程式的執行模式
呼叫程式
被呼叫程式
sub( )
3
1
4
2 call sub( )
*
5
6
呼叫程式執行
呼叫sub( )副程式
控制流程轉移到sub( )
副程式
sub( )副程式執行
sub( )副程式執行完畢,
控制流程轉移回呼叫
程式
呼叫程式繼續執行
9
副程式的種類

程序(procedure)


沒有傳回值
函式(function)



函式與程序類似,最大的不同之處是函式會傳
回一個值
函式本身亦具有型態
函式也可作為運算式的一部分
10
求最大公因數 程式段

Pascal
function gcd(a, b: integer):integer;
begin
if b = 0 then
gcd := a
else gcd := gcd(b, a mod b)
end;
11
求最大公因數 程式段

C
int gcd(a, b)
int a, b;
{
if (b = = 0) return (a);
else return (gcd(b, a%b));
}
12
參數傳遞的方法

常見參數傳遞的方法





傳值呼叫法
傳址呼叫法
傳名呼叫法
數值結果呼叫法
本文呼叫法
13
傳值呼叫法 (call by value)




呼叫程式呼叫被呼叫程式時,將呼叫程式
中實際參數的值,傳給被呼叫程式中對應
的型式參數
實際參數與相對應的型式參數不會佔用相
同的記憶體空間
沒有副作用(side effect)
只提供 in mode 參數
14
傳值呼叫法 (call by value)

優點


實際參數的值只能被讀取,在副程式執行的過
程中不會因為更改型式參數的值連帶地將實際
參數的值更改
缺點

需配置額外的記憶體空間給型式參數使用
15
傳址呼叫法 (call by address)





又稱為call by reference或call by location
呼叫程式呼叫被呼叫程式時,將呼叫程式
中實際參數的位址,傳給被呼叫程式中對
應的型式參數
實際參數與對應的型式參數會佔用相同的
記憶體空間
有副效應
提供 in out mode 參數
16
傳址呼叫法 (call by address)

優點


不需配置額外的記憶體空間給型式參數使用
缺點

在副程式執行的過程中會因為更改型式參數的
值連帶地將實際參數的值更改(副作用)
17
傳名呼叫法 (call by name)



呼叫程式呼叫被呼叫程式時,將呼叫程式
中實際參數的名稱,傳給被呼叫程式中對
應的型式參數
將副程式中所有型式參數的名稱以實際參
數的名稱來替代
實際參數與對應的型式參數會佔用相同的
記憶體空間
18
傳名呼叫法 (call by name)

優點

具有較大的彈性,可提供不同型式的實際參數
讓同一個副程式做不同的工作
當實際參數為簡單變數時,傳名呼叫法之處理方
式與傳址呼叫法相同
 當實際參數為常數時,傳名呼叫法之處理方式與
傳值呼叫法類似


缺點

程式難讀、不易製作、執行速度較慢及不易學
習
19
數值結果呼叫法 (call by value result)




呼叫程式呼叫被呼叫程式時,將呼叫程式
中實際參數的值,傳給被呼叫程式中對應
的型式參數
實際參數與型式參數不會佔用相同的記憶
體位置
當被呼叫程式執行完畢時,會將被呼叫程
式中型式參數的值,傳回給呼叫程式中對
應的實際參數
提供 in out mode 參數
20
範例

設有一程式語言的副
程式如下:
PROCEDURE
P(A,B,C);
B=C;
RETURN(A+C);
END;

若X=1,Y=2,試問執
行"R←P(X,X,X+Y)"
之後對於 (a)傳名呼叫
法 (b)傳值呼叫法 (c)
傳址呼叫法三種不同
的參數傳送的方式,
R之值各為若干?
21
範例
若右例以:
(a)傳名呼叫法
(b)傳值呼叫法
(c)傳址呼叫法
(d)數值結果呼叫法
四種不同的引數傳送的方
式,A之值各為若干?

procedure P(X,Y,Z);
begin
Y:=Y+1;
Z:=X+X;
end;
begin
A:=1;
B:=1;
P(A+B,A,A);
print A;
end.
22
本文呼叫法 (call by text)


在呼叫時不把實際參數閉合(closure),而
是一直延遲到遇到型式參數時再予閉合
用被呼叫程序環境閉合時的狀態計算實際
參數之值


“閉合”是指一程序與其相關環境繫結在一起
之過程
LISP之FEXPR版本採用此法
23
本文呼叫法範例

var x : integer;
procedure text(y);
var x : integer;
begin
x := 5;
writeln(y);
end;


本文呼叫法處理結果為 5
傳名呼叫法處理則結果為 4
begin
x:=4;
text(x);
end.
24
別名 (aliasing)


兩個或兩個以上名稱不同的變數,佔用相
同的記憶體空間
別名形成的原因




參數傳遞時採用傳址呼叫法
變異記錄(variant record)
指標
Fortran的“equivalence”敘述
25
別名 現象對程式執行結果的影響

已知某一算術運算式(arithmetic expression):
A×FUN(A)+A
若執行此運算式前之A值為2,FUN(A)傳
回值為3,而執行此運算式時由於副作用
(Side effect)造成A值變成6,則下列何者不
可能是此運算式執行後之值?
(A) 20 (B) 24 (C) 12 (D) 10
26
超荷法 (overloading)


如果結構(constructure),因為引數的型態
不同而具有不同的意義的話,則稱此現象
為超荷法
範例

A+B



若A,B為整數則執行整數加法運算;若A,B為
實數則執行實數加法運算
Algol68中關於ABS()函數
C++
27
通用性函數 (generic function)



允許參數傳遞的對象為“型態”
主要的用途是可排除程序對資料型態的依
賴性
優點



可減少程式碼的長度
可減少撰寫程式時,發生錯誤的可能性
代表性的語言是ADA
28
ADA 通用性函數範例

generic
type T is private;
package P is
procedure SWAP (A, B: in out T);
end P;
package body P is
procedure SWAP (A, B: in out T) is
temp : T;
begin
temp := A; A := B; B := temp;
end;
end P;
29
ADA 通用性函數範例

procedure SWAPINT is new SWAP (integer);
procedure SWAPINT(A,B:in out integer) is
temp : integer;
begin
temp:=A;A:=B;B:=temp;
end;
30
ADA 通用性函數範例

procedure SWAPINT is new SWAP (real);
procedure SWAPINT(A,B:in out real) is
temp : real;
begin
temp:=A;A:=B;B:=temp;
end;
31
六種常見的副程式呼叫方式






呼叫∕返回副程式(call∕return subroutine)
遞迴副程式(recursive subroutine)
例外處理副程式(exception handling subroutine)
並行常式(coroutine)
排程副程式(scheduled subroutine)
並行程序(concurrent subroutine)
32
呼叫∕返回副程式


與一般的副程式呼叫是相同的
傳統的呼叫/返回副程式須滿足以下五項限
制





不允許遞迴呼叫
副程式被呼叫時,必須有明顯的呼叫敘述
副程式被呼叫時,應從頭開始執行
副程式被呼叫時,控制流程應立即轉移
單一執行順序
33
遞迴副程式


若副程式可以呼叫本身或透過其他的副程
式來呼叫本身
直接遞迴


副程式可以自己呼叫自己
間接遞迴

副程式可以透過其他的副程式來呼叫自己
34
例外處理副程式


處理例外情況的副程式
首創例外處理的語言為 PL/1
35
並行常式



一種交換關係
假設有二個程序分別是P
與Q,其中程序P可以啟動
Q的執行,而程序Q也可以
啟動程序P的執行
當程序啟動另一程序的執
行時,會先將自己目前的
狀態儲存起來,下次被啟
動執行時,會由上次執行
結束之處繼續往下執行,
而非從頭開始執行
Process P
(2)
(3)
(1)
resume Q
Process Q
(4)
resume P
(5)
36
排程副程式



一般的副程式呼叫是在被呼叫時,立即執行副程
式
排程副程式在被呼叫時,並未立即被執行而是須
在符合某種條件下才會被啟動執行
範例


CALL SUB AT TIME=100
 代表當時間為100時,副程式SUB才會被啟動。
CALL SUB1 AFTER SUB2
 代表當副程式SUB2執行完畢後,副程式SUB1才會被
啟動
37
並行程序

同時執行的程式段即稱為並行程序
38
精選習題





傳名呼叫法、傳值呼叫法及傳址呼叫法在資訊定
址值方面有早晚之分,試列出早晚的順序。
試問在JAVA語言中,函數之間的參數如何傳遞?
簡釋傳值呼叫法與傳址呼叫法,並舉例說明何種
狀況二者可得相同的結果,在何種狀況下二者所
得不同。
在何種情況之下,傳址呼叫法和傳值結果呼叫法
會得到不同的結果?
在何種情況下,傳名呼叫法和本文呼叫法會得到
不同的結果。
39