【C++ 筆記】函數(Function)(下) - part 11 === 目錄(Table of Contents): [TOC] --- 很感謝你點進來這篇文章。 你好,我並不是什麼 C++、程式語言的專家,所以本文若有些錯誤麻煩請各位鞭大力一點,我極需各位的指正及指導!!本系列文章的性質主要以詼諧的口吻,一派輕鬆的態度自學程式語言,如果你喜歡,麻煩留言說聲文章讚讚吧! 函數參數的傳遞方式 --- > 如果函數要使用參數,則必須宣告接受參數值的變數。這些變數稱為函數的形式參數。 形式參數如同局域變數(Local Variable),自從函數被呼叫開始,就被建立,函數程式碼結束後,則形式參數自動被刪除。 呼叫函數時,有三種參數的傳遞方式,如下: * 傳值呼叫(call by value) * 傳址呼叫(call by address / call by pointer / pass by address) * 傳參(考)呼叫(call by reference) 這三種方式有什麼差異呢?請繼續看下去~ ### 傳值呼叫(call by value) --- 傳值呼叫中,被傳遞的參數實際值會複製給形式參數,因此無論如何修改函數內的形式參數皆不會改變到實際參數值。 這就好像世界上總有許多同名的人,但他們本質上是不同的,比如有很多叫 Amy 的人,但是有的 Amy 很有錢,有的超窮等等。 :::success Call by value 所引用的變數僅為當時的數值,而非變數本身。 ::: 具體而言,看以下的範例即可易懂,這是最常見的 swap() 函數程式碼。 ```cpp= #include <iostream> using namespace std; // 函數宣告 void swap(int x, int y); // 函數定義 void swap(int x, int y) { int temp; temp = x; /* 保存 x 的值 */ x = y; /* 把 y 指定给 x */ y = temp; /* 把 x 指定给 y */ return; } int main () { int a = 100; int b = 200; cout << "交換前,a 的值:" << a << endl; cout << "交換前,b 的值:" << b << endl; // 呼叫函數交換值 swap(a, b); cout << "交換後,a 的值:" << a << endl; cout << "交換後,b 的值:" << b << endl; return 0; } ``` 輸出結果: ``` 交換前,a 的值:100 交換前,b 的值:200 交換後,a 的值:100 交換後,b 的值:200 ``` 可見 a、b 值經交換函數後,輸出結果沒有任何變化。 那要如何使 a、b 值交換呢?請繼續看下去。 ### 傳址呼叫(call by address / call by pointer) --- 傳址呼叫就是將參數的地址複製給形式參數,所以在函數內修改形式參數會影響實際參數。 與傳值調用範例程式碼寫法有些許不同,因為需要將地址複製給形式參數,所以需要使用指標於函數內。 :::success 「傳址呼叫」是將變數的記憶體位址傳遞給函數的參數,而不是直接傳遞變數的值。因此,函數內部可以透過該位址存取並修改外部變數的數值。 ::: ```cpp= #include <iostream> using namespace std; // 函數宣告 void swap(int *x, int *y); // 函數定義 void swap(int *x, int *y) { int temp; temp = *x; /* 保存地址 x 的值 */ *x = *y; /* 把 y 指定给 x */ *y = temp; /* 把 x 指定给 y */ return; } int main () { int a = 100; int b = 200; cout << "交換前,a 的值:" << a << endl; cout << "交換前,b 的值:" << b << endl; /* 呼叫函數交換值 * &a 表示指向 a 的指標,即變數 a 的地址 * &b 表示指向 b 的指標,即變數 b 的地址 */ swap(&a, &b); cout << "交換後,a 的值:" << a << endl; cout << "交換後,b 的值:" << b << endl; return 0; } ``` 輸出結果: ```cpp= 交換前,a 的值: 100 交換前,b 的值: 200 交換後,a 的值: 200 交換後,b 的值: 100 ``` 可以發現 a、b 值成功交換了。 ### 傳參考呼叫(call by reference) --- > 向函數傳遞參數的傳參呼叫方法,把參考的位址複製給形式參數。在函數內,此參考用於存取呼叫中要用到的實際參數。這意味著,修改形式參數會影響實際參數。 光看定義可能有點不太懂,但其實就只是在參數前面加上"&"而已,參數都不需要像傳址呼叫一樣改成指標,因為加上 & 就表示傳參的記憶體位址。 重點是傳參考呼叫不須使用指標即可達到修改外部變數的目的。 :::success 「傳參考呼叫」是將變數本身的參考傳遞給函數,使函數能直接操作該變數的內容而非其副本。 ::: :::info 參考(Reference)是指一種資料型態,允許程式間接存取記憶體中的特定資料。這些資料可以是變數,參考本身並不包含數據(Data),而是指向數據在記憶體中的位址。 當傳遞參考時,實際上是傳遞了資料的「位址」,而不是資料的副本,因此對資料的修改將直接影響原始數據,所以傳參考呼叫為何能與傳址呼叫具有同樣的效果。 ::: 有關於參考的解釋詳情請至我的筆記 part 14:[傳送門點我](https://hackmd.io/@LukeTseng/B14p365NJe) 具體範例請看: ```cpp= #include <iostream> using namespace std; // 函數宣告 void swap(int &x, int &y); int main () { int a = 100; int b = 200; cout << "交換前,a 的值:" << a << endl; cout << "交換前,b 的值:" << b << endl; /* 呼叫函數交換值 */ swap(a, b); cout << "交換後,a 的值:" << a << endl; cout << "交換後,b 的值:" << b << endl; return 0; } // 函數定義 void swap(int &x, int &y) { int temp; temp = x; /* 保存地址 x 的值 */ x = y; /* 把 y 指定给 x */ y = temp; /* 把 x 指定给 y */ return; } ``` 輸出結果: ``` 交換前,a 的值: 100 交換前,b 的值: 200 交換後,a 的值: 200 交換後,b 的值: 100 ``` 傳參考呼叫的應用場景: * 修改外部變數:如上例所示,透過函數修改傳入的變數。 * 減少開銷:特別是在傳遞大物件或複雜資料結構時,引用傳遞可以避免不必要的拷貝操作。 * 傳回值最佳化:透過引用傳回函數的局部變量,避免了傳回值拷貝的開銷。 > 傳參考呼叫是 C++ 中的重要技術,可以提高程式碼的效率和靈活性。了解和熟練使用引用呼叫對於編寫高效的C++程式非常有幫助。 來源:https://www.runoob.com/cplusplus/cpp-function-call-by-reference.html 總結 --- 解釋: * 傳值呼叫(call by value):傳遞參數時引用的不是變數本身,而是它的值,所以並沒有引用到他的記憶體位址。 * 傳址呼叫(call by address):傳遞參數時將變數的記憶體位址傳遞給函數的參數,而不是直接傳遞變數的值。->所以能改變變數的值 * 傳參考呼叫(call by reference):將變數本身的參考傳遞給函數,使函數能直接操作該變數的內容而非其副本(不是變數的copy,如果直接改copy值那對初始的變數完全沒影響)。 論其功用而言: * 傳值呼叫(call by value):適合小型資料型態,簡單且安全,但不適合大型資料結構,因為會造成效能損耗。 * 傳址呼叫(call by address):允許直接運算原始變數,適合需要修改多個變數或處理大型資料結構時使用。 * 傳參考呼叫(call by reference):與傳址類似,但語法更簡潔且不需要手動提取(Dereference),適合需要修改原始變數的情況。 參考資料 --- [【教學】call by value, call by address, call by reference 差別在哪?-橘子亂說話|痞客邦](https://wayne265265.pixnet.net/blog/post/112556555) [C++ function call by reference](https://www.tutorialspoint.com/cplusplus/cpp_function_call_by_reference.htm) [C++ 函数 | 菜鸟教程](https://www.runoob.com/cplusplus/cpp-functions.html) [C++ 传值调用 | 菜鸟教程](https://www.runoob.com/cplusplus/cpp-function-call-by-value.html) [C++ 指针调用 | 菜鸟教程](https://www.runoob.com/cplusplus/cpp-function-call-by-pointer.html) [C++ 引用调用 | 菜鸟教程](https://www.runoob.com/cplusplus/cpp-function-call-by-reference.html)
×
Sign in
Email
Password
Forgot password
or
Sign in via Google
Sign in via Facebook
Sign in via X(Twitter)
Sign in via GitHub
Sign in via Dropbox
Sign in with Wallet
Wallet (
)
Connect another wallet
Continue with a different method
New to HackMD?
Sign up
By signing in, you agree to our
terms of service
.