[爆卦]Call by reference是什麼?優點缺點精華區懶人包

為什麼這篇Call by reference鄉民發文收入到精華區:因為在Call by reference這個討論話題中,有許多相關的文章在討論,這篇最有參考價值!作者yraid (yraid)看板Grad-ProbAsk標題Re: [理工] 想請問97清大資 最...


※ 引述《jas1123kimo (傑森)》之銘言:
: http://ppt.cc/og7m
: call by value by value-result by reference的差別在哪裡~
: 要怎麼呢?~麻煩大加了!感謝

幾個參考資料
http://c2.com/cgi/wiki?CallByValueResult

http://c2.com/cgi/wiki?CallByReference

http://0rz.tw/aSrf4


(1) Call by value: "you get a copy of the data or object"

以題目的舉例而言,swap將參數first、second以pass by value的方式傳進來,
也就是說,在swap裡面不管將first、second這兩個變數如何更改,
原本的caller中的變數並不會被改變;

舉例:
int x = 1; //global variable

void foo(int a) //a被copied成1
{
// a is 1; x is 1
a = 3;
// a is 3; x is 1
x = 4;
// a is 3; x is 4
}

void main()
{
// x is 1
foo(x);
// x is 4
}


(2)Call by reference:"you get an alias of the data or object"

A ParameterPassing mode where a reference (or if you want to be politically
incorrect, a pointer) to the actual parameter is passed into the formal
parameter; when the callee needs the formal parameter it dereferences the
pointer to get it.

以題目舉例而言,swap將參數first、second以pass by reference的方式傳進來,
那麼這兩個參數在swap中如果被更改,那原本caller中的變數也會被改變;
以上面的例子來說,那一行就會印100。

舉例:
int x = 1; //global variable

void foo(int a) //有aliasing,a和x都指向同一個位置
{
// a is 1; x is 1
a = 3
// a is 3; x is 3
x = 4
// a is 4; x is 4
a = 5
// a is 5; x is 5
}

void main()
{
// x is 1
foo(x);
// x is 5
}



(3)Call by value-result

In CallByValueResult, the actual parameter supplied by the caller is copied
into the callee's formal parameter; the function is run; and the (possibly
modified) formal parameter is then copied back to the caller.

The (semantic) differences between CallByReference and CallByValueResult are:

"No alias is created between the formal and actual parameters. If lexical
scoping is used, the difference can be apparent."

舉例:
int x = 1; //global variable

void foo(int a) //因為沒有aliasing,foo將1 copied給a,
a最後被assigned成3,foo再將3 copied回main。
{
// a is 1; x is 1
a = 3;
// a is 3; x is 1
x = 4; //因為沒有aliasing,雖然這行將x改為4,
但當foo結束之後,會把3 copied回main,因此x最後為3
// a is 3; x is 4
}

void main()
{
// x is 1
foo(x);
// x is 3
}



附註:

lexical scoping:
也叫做static scoping,簡單來說就是變數的scope只在它定義的那個區塊,
離開了那個區塊,那個變數就不再存在。


來看這個例子:

x=1 # this is a global variable
function g () { echo $x ; x=2 ; }
function f () { local x=3 ; g ; }
f # does this print 1, or 3?
echo $x # does this print 1, or 2?

如果是lexical scoping的話,
最後兩行分別會印1、2,
因為g的定義在f的外面,所以g他不知道f將 x assign成3,
所以先echo $x,會印1,然後再將 x assign成2
最後一行的echo $x會印2;

順便一提,相反的就是叫做dynamic scoping,
其變數的scope只要function還在running就會存在,
因此,上面的例子就會先印3(看得見f將x assign成3)
再印1(global variable的scope是整個程式)

總結,Call by reference和Call by value-result的差別在於,
Call by reference有引進aliasing,Call by value-result沒有。




--
以上騙P幣QQ,有錯請各方高手指正<(_ _)>

--
※ 發信站: 批踢踢實業坊(ptt.cc)
◆ From: 111.240.194.204
jas1123kimo:你根本超強! 01/26 09:28

後來想起來以前老師上課說的,
「Aliasing」的意義就像是綽號,
也就是caller裡給的變數,它的綽號就是callee傳進來的參數,
對程式來說,這兩個變數會被視為同一個~
所以callee的參數被改變,caller中的變數也會跟著被改變。

rnf0:call by value-result就是macro 01/26 10:43
rnf0:好像有點不同XD macro比較低階 01/26 10:46

印象中macro是在compile time的時候把程式碼展開預先處理吧,
藉由compiler的preprocessor~

call by value-"result" 好像名字就有隱含著它的意義了XDD
傳參數方式是call by value,但是當副程式執行完會把result複製回去
※ 編輯: yraid 來自: 111.240.194.204 (01/26 11:14)

你可能也想看看

搜尋相關網站