三种传值方式遇上两个数的交换
最近在学习数据结构的时候发现以前学的C++的有些东西都忘了,特别是老师提到的三种传值的方式——单向值传递,地址传递,双向引用传递;为此,我这里用如何交换两个数的例子来说明一下三种传值方式的机制。
先看看源代码:
1 #include<iostream> 2 using namespace std; 3 int swap1(int m1,int m2)//单向值传递 4 { 5 int temp = m1; 6 m1 = m2; 7 m2 = temp; 8 cout<<m1<<" "<<m2<<endl; 9 return 0; 10 11 } 12 int swap2(int *m1,int *m2)//地址传递 13 { 14 int temp = *m1; 15 *m1 = *m2; 16 *m2 = temp; 17 cout<<*m1<<" "<<*m2<<endl; 18 return 0; 19 20 } 21 int swap3(int &m1,int &m2)//双向引用传递 22 { 23 int temp = m1; 24 m1 = m2; 25 m2 = temp; 26 cout<<m1<<" "<<m2<<endl; 27 return 0; 28 } 29 void main() 30 { 31 int a1 = 13,b1 = 23; 32 swap1(a1,b1); 33 cout<<a1<<" "<<b1<<endl; 34 cout<<endl; 35 int a2 = 11,b2 = 22; 36 swap2 (&a2,&b2);//将地址的值作为函数的参数 37 cout<<a2<<" "<<b2<<endl; 38 cout<<endl; 39 int a3 = 10,b3 = 20; 40 swap3(a3,b3); 41 cout<<a3<<" "<<b3<<endl; 42 }
程序运行截图:
一·单向值传递:
在上面的代码中,第一个交换函数使用的是单向传值,从程序运行结果看,a1与和b2并没有交换,这是为什么呢,大家再看一下这个程序:
#include<iostream> using namespace std; void add(int m) { m = m + 1; } void main() { int n = 10; add(n); cout<<n<<endl; }
最后输出的结果是10,而并非11,这就很好的解释了单向传递:数值只能由实参传给形参,而不能倒过来,即由形参传给实参,这是因为这里调用函数swap()时,把n = 10 这个数值10传给了形参m,当调用函数swap()完之后,虽然m的值是由10加了一个1成了11,但是这并不会被保存起来,因为当调用函数完之后所有的形参都会被释放,然而这一切与n并没有关系,因为是n的数值作为形参,而并不是n本身,程序运行结果n的值并不会改变。
二.地址传递:
第二个函数使用的是地址传递方式,从程序运行结果来看使用这种传值的方式可以交换两个数,这是什么原理呢,我们将上面的小程序修改一下:
#include<iostream> using namespace std; void add(int *m)//使用指针达到实参与形参双向传递的功能 { *m = *m + 1; } void main() { int n = 10; add(&n);//把n的地址作为形参 cout<<n<<endl; }
程序运行的结果是11,这种改变就是地址传递的作用,我们在调用函数时,把n的地址(&n的作用是去取n的地址)作为形参,这样形参就和实参挂钩了,形参m和实参n共用一个地址,调用函数形参加了一个1,m变成了11,所以此地址上的值变成了11,而实参n的地址就是形参m的地址,所以实参n的值也变成了11。
三.引用传递:
上文最后一个交换函数使用的是引用传递的方式,这种传值的方法也可以交换两个数。引用传递就是给实参取了个别名。引用传递没有自己单独的内存空间,他和实参共用一段内存,对形参的任何修改即相当于对实参的相同方式的修改,实现的是形参和实参的双向传递。这种传递方式好记又好用。