大一程設
東華大學
東華大學資管系
基本程式概念
資管經驗分享
在 如何看 block,不再搞混變數範圍,區域變數與全域變數 有跟大家提到了其中一種參數傳遞方法 call-by-value,但是這個方法會在呼叫函式時配置與傳入參數不同的記憶體區塊,導致不能更改同一個位置的內容,但大多時候,我們是需要修改相同變數的,而在 C++ 中我們有兩種方法,一種稱為 call-by-reference,一種叫做 call-by-address。
call-by-address 會在教 pointer(指標) 的時候才談,這一篇筆記只會講 call-by-value 與 call-by-reference。
如果 call-by-reference 跟 call-by-address 學不會,那代表你沒長大,筆記跟上課要記熟,不會要問到懂。
Orange
call-by-value 我其實已經在 這裡 講得很清楚了,還有 錄影 講解給你們聽,就超連結到那邊去吧,就不佔這篇筆記的篇幅了~
在正式談論 call-by-reference 之前,我想再帶大家更細看 function 這個東西。
在一般宣告函式與呼叫函式時會有如下的長相,相信大家都已經熟悉了。
這邊有一些專有名詞想要讓大家知道 =>
請注意紅筆地方,務必明確知道我在說什麼
所以學過 call-by-value 我們可以知道,在呼叫 call-by-value 樣態的函式的時候,AP 跟 FP 會佔用不一樣的記憶體,假設我們在 main 中宣告的變數作為參數傳進一個 function 中,則該變數是在 main 宣告並被配置一塊記憶體,但呼叫函式時我們只把 AP 的值傳進 function 中,而 FP 會再另外配置新的記憶體,所以兩者所在的記憶體位置並不相同。
而這個 AP 與 FP 所操縱的記憶體位置不同的現象我們稱為 No Side Effect(沒有副作用)
所以 AP 與 FP 若操縱相同的記憶體位置,我們就稱為 Side Effect,call-by-reference 馬上就會談到這個現象。
但通常大家都記英文,沒人在講中文
Orange
call-by-reference 是 C++ 獨有的參數傳遞方式,在 C 語言內並沒有。
call-by-reference 能夠讓設計師去操弄相同位置的變數,那要怎麼做到呢?我們來看個例子。
可以看到在第一行我們 swap 函式的參數內容中,有別以往我們看到的參數宣告方式,我們加上了 "&" 這個符號。
而在宣告變數時加上 "&" 這個符號,我們稱這樣的變數為參考變數 (reference variable)
跟之前補充的取得變數位址的 "&" 是在不同的情境哦,一個是在宣告,一個是在陳述。
針對取址有疑問的話回去看之前的影片
Orange
接下來說明參考變數的運作與宣告方式:
這邊的運作方式是,我們替 x 這個變數取一個別名叫做 count。
就像綽號一樣,我的綽號是 Orange,本名是柳成彥,你用這兩個方式叫我,都是指我。而參考變數的運作方式就是如此。由此可知,x 的參考變數 count,會去操控與 x 相同一塊記憶體位址。
大家先藉由看這個案例想想看,在心中決定一個答案,再把這個案例跑跑看,看是不是 count 真的會改變 x 的值。是不是與你心中決定的答案相同。
如果參考變數你確定懂了,就可以繼續往下看 call-by-reference 了。
先把剛剛的範例再貼上一次,如下。
第一行內,藉由剛剛的說明我們可以瞭解 args1 與 args2 各為一個參考變數,所以我們在 main 呼叫 swap 的時候,傳入的 a 跟 b 分別被取了別名為 args1 跟 args2,像這樣。
所以 args1 會操控 a 的那塊記憶體,args2 會操控 b 的那塊記憶體。
既然都操縱同樣一塊記憶體,在這個函式結束回到 main 時,a 跟 b 的值自然就會互換,因為 a 跟 b 的記憶體是在 main 內宣告,main 還沒結束,記憶體還沒釋放,所以做更改時會確實的交換兩者的值。
若你還是不信,就用取址運算子去印看看這些變數的記憶體位址吧,看看 a 跟 args1 的記憶體位址是不是相同,b 跟 args2 也同理。
還記得我講解 call-by-value 的影片時所畫的記憶體配置圖嗎?
試試看 call-by-reference 你們能不能畫出跟我一樣的結果。
Orange
所以總結,call-by-reference 操控的 FP 與 AP 是相同塊的記憶體,故呼叫函式時對 FP 的操作會影響 AP,由此可知這種參數傳遞方式會產生 Side Effect。
到了這邊如果你還是不懂,或是想實際看我講解一次,影片一樣附給你們。
看看上面兩句定義哪種你比較容易理解,但都是一樣的意思。
先舉個簡單的例子。
根據上面的例子,我有三個實作加法的函式,但是每個的功能各不相同,如果都要取不同的名字,有時候有點麻煩,但是 C++ 提供我們取同名字但根據參數的不同來觸發不同效果的功能,這就是函式多載。
像第二個加法我們實作浮點數的加法,第三個實作三個整數的加法,所需的參數的數量、型別都不相同,在程式執行時只要我們有確實的定義好函式規範,電腦是會認得這些差異的。
而函式多載的概念雖然簡單,但卻極為重要,在程式設計師的求學生涯中,絕對跑不掉物件導向程式設計,而對建構子的宣告就是運用函式多載的概念。
甚至是難度更高的抽象類別或是介面,對於函式多載的要求有時又更廣泛。