初学 \(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\)