初學 \(c++\),一直搞不懂其參數傳遞方式。故找到一篇不錯的文章:劉志華的深刻探討C++語言中參數傳遞問題。親自實踐一遍,並做此記錄,以加深印象。
c++
本文主要分爲五個小部分,下面依次做總結。
數組
簡單變量做參數的傳遞方式是按值傳遞,在這種傳遞方式下,在函數體中對形參的修改不會影響實際參數的值,由於它們使用各自的存儲空間。函數
下面即是一個簡單變量做參數的實例。調用 swap 參數同時把 \(x\) 的值傳送給形參 \(a\),把 \(y\) 的值傳送給形參 \(b\),在函數體中對形參 \(a\) 和 \(b\) 的操做是與對應的實參 \(x\) 與 \(y\) 無關的,由於它們使用各自的存儲空間。spa
void swap(int a, int b) { int temp = a; a = b; b = temp; } int main() { int x=45, y = 12; swap(x, y) cout<<"x="<<x<<' '<<"y="<<y<<endl; return 0; }
輸出結果是:\(x=45,\, y=12\). 可見在這種傳遞方式下,在函數體中對形參的修改不會影響實際參數的值。指針
指針自己是一個變量,特殊之處在於它的值是一個地址,於是能夠經過指針來間接訪問另一個內存地址。當函數的形式是指針時,它的實際參數的值必須是一個地址。因爲指針做形參,所以對應的形參的實參共用同一個內存單元,形參值的改變將影響實參值。下面繼續看一個實例。code
void swap(int* a, int* b) { int temp = *a; *a = *b; *b = temp; } int main() { int x = 45; int y = 12; swap(&x, &y); cout<<"x="<<x<<' '<<"y="<<y<<endl; return 0; }
輸出結果是:\(x=12,\, y=45\). 可見在這種傳遞方式下,在函數體中對形參的修改將影響實際參數的值。內存
因爲引用做形參,所以對應的形參和實參就是同一個內存單元,形參值的改變也將影響實參值。字符串
void swap(int& a, int& b) { int temp = a; a = b; b = temp; } int main() { int x = 45; int y = 12; swap(x, y); cout<<"x="<<x<<' '<<"y="<<y<<endl; return 0; }
輸出結果是:\(x=12,\, y=45\). 可見在這種傳遞方式下,在函數體中對形參的修改將影響實際參數的值。class
引用傳送的好處是不須要爲形參分配新的存儲空間,從而節省存儲,另外就是如實例這樣,可以使對形參的操做反映到實參上。有時,既爲了使形參共享實參的存儲空間,又不但願經過形參改變實參的值,則應當把該形參說明爲常量引用,如:變量
void swap(const int& a, const int& b)
在這種狀況下,只能讀取引用參數 \(a\) 和 \(b\) 的值,不可以修改它們的值,由於它們是對應實參的別名,從而杜絕了對實參的有意或無心的破壞。
看下面一個實例。
int sum(int a[], int n) { int f = 1; for (int i=0; i<n; i++) { f *=a[i]; } return f; } int main() { const int N = 6; int b[N] = {1,2,3,4,5,6}; int x = sum(b, 6); int y = sum(&b[2], 4); int z = sum(b+3, 3); cout<<"x="<<x<<' '<<"y="<<y<<' '<<"z="<<z<<endl; return 0; }
輸出結果是:\(x=720,\, y=360,\,z=120\).
該函數包含一個主函數和一個 sum 函數,其功能是求出一維整型數組全部元素之積並返回。
看下面一個實例。
char* sss(char *sp, char* dp) { if (*sp == '\0') { *dp = '\0'; return dp; } int i=0; // i 是記錄 dp 中字符個數 int j; for (char* p=sp; *p; p++) { //掃描 sp 所指字符串中的每一個字符位置 for (j=0; j<i; j++) { if (*p == dp[j]) break; // 當 *p 與 dp[0] 至 dp[i-1] 之間的任一元素相同則比較過程結束 } if (j >= i) dp[i++] = *p; // 若 dp 數組的前 i 個元素不等於 *p, 則把 *p 寫入 dp[i] 元素中 } dp[i] = '\0'; // 寫入字符串結束符 return dp; } int main() { char a[15] = "abcdeabcde"; char b[15]; char* c1 = sss(a, b); cout<<"c1="<<c1<<' '<<"a="<<a<<' '<<"b="<<b<<endl; char* c2 = sss(a+4, b); cout<<"c2="<<c2<<' '<<"a="<<a<<' '<<"b="<<b<<endl; return 0; }
sss 函數的功能是把 sp 所指向的字符串去掉重複字符後拷貝到 dp 所指向的字符數組中,並返回 dp 指針。在主函數中第一次調用 sss 函數時,分別以 \(a\) 和 \(b\) 做爲實參,第二次調用時分別以 \(a+4\) (即 \(a[4]\) 的地址)和 \(b\) 做爲實參。該程序運行結果是:
\(c1=abcde\,\,a=abcdeabcde\,\, b=abcde\)
\(c2=eabcd\,\,a=abcdeabcde\,\, b=eabcd\)