关于四个swap函数的归类

    在学习C语言函数那一章节的时候我们第一次认识了swap。当时书上举这个例子是为了说明函数的“单向值传递”原理,即在函数调用的时候,实参总是将自己的值单向传递给形参,而不能反过来,并且在这个过程中形参的改变不会导致实参的改变。后来,我们又学习了指针,然后知道在函数调用的时候,实参还可以是一个变量的地址或者指针,即所谓的传址,并且知道传址调用过程中形参的改变会导致实参变化。再后来,我们还学习了C++程序设计语言,了解到在C++中还有一种函数参数的传递方式即“引用调用”,而且引用调用过程中形参的变化也会引起实参的变化!

    上面说了那么多,无非说了两件事,第一,函数参数的传递方式有三种方式,即传值、传址和引用调用;第二,传值调用中形参的改变不会导致实参的变化,而传址和引用调用中形参的变化则会导致实参的变化。为了加深印象,下面给出几个关于swap函数的例子:


先看两个传值调用的程序:

--------------------------------------------------------------------------------------------

//example_1

#include<iostream>
using namespace std;
void swap(int a,int b)
{
 int t;
 cout<<"In  swap,Begin:"<<"a="<<a<<",b="<<b<<endl;
 t=a;
 a=b;
 b=t;
 cout<<"In  swap,End:"<<"a="<<a<<",b="<<b<<endl;
}
int main()
{
 int x=3,y=9;
 cout<<"Befor swap:x="<<x<<",y="<<y<<endl;
 swap(x,y);
 cout<<"After swap:x="<<x<<",y="<<y<<endl;
 return 0;
}
--------------------------------------------------------------------------------------------

结果为:

Befor swap:x=3,y=9

In swap,Begin:a=3,b=9

In swap,End:a=9,b=3

After swap,x=3,y=9

显然在函数调用过程中,形参发生了改变,但是实参没有发生变化,这是最典型的传值调用方式。

--------------------------------------------------------------------------------------------

//example_2

#include<iostream>
using namespace std;
void swap(int *a,int *b)
{
 int *t;
 cout<<"In  swap,Begin:"<<"a="<<a<<",b="<<b<<endl;
 t=a;
 a=b;
 b=t;
 cout<<"In  swap,End:"<<"a="<<a<<",b="<<b<<endl;
}
int main()
{
 int x=3,y=9;
 cout<<"Befor swap:x="<<x<<",y="<<y<<endl;
 swap(&x,&y);
 cout<<"After swap:x="<<x<<",y="<<y<<endl;
 return 0;
}
--------------------------------------------------------------------------------------------

结果为:

Befor swap:x=3,y=9

In swap,Begin:a=0012FF7C,b=0012FF78

In swap,End:a=0012FF78,b=0012FF7C

After swap:x=3,y=9

在函数调用过程形参发生了交换,但是实参没有发生交换,这种方式表面上是传址(实参为地址),但是由于函数调用过程中实际上没有针对实参作出任何操作,其本质还是传值调用,故也将其划为传值调用。


接下来分别看两个传址和引用调用的粒子:

//example_3

#include<iostream>
using namespace std;
void swap(int *a,int *b)
{
 int t;
 cout<<"In  swap,Begin:"<<"a="<<a<<",b="<<b<<endl;
 t=*a;
 *a=*b;
 *b=t;
 cout<<"In  swap,End:"<<"a="<<a<<",b="<<b<<endl;
}
int main()
{
 int x=3,y=9;
 cout<<"Befor swap:x="<<x<<",y="<<y<<endl;
 swap(&x,&y);
 cout<<"After swap:x="<<x<<",y="<<y<<endl;
 return 0;
}

--------------------------------------------------------------------------------------------
结果为:

Befor swap:x=3,y=9

In swap,Begin:a=0012FF7C,b=0012FF78

In swap,End:a=0012FF78,b=0012FF7C

After swap:x=3,y=9

可见在函数调用前后,形参没有发生变化,但是实参发生了变化,进行了交换。这是因为对形参的操作实际上就是对实参的操作。

--------------------------------------------------------------------------------------------

//example_4

#include<iostream>
using namespace std;
void swap(int &a,int &b)
{
 int t;
 cout<<"In  swap,Begin:"<<"a="<<a<<",b="<<b<<endl;
 t=a;
 a=b;
 b=t;
 cout<<"In  swap,End:"<<"a="<<a<<",b="<<b<<endl;
}
int main()
{
 int x=3,y=9;
 cout<<"Befor swap:x="<<x<<",y="<<y<<endl;
 swap(x,y);
 cout<<"After swap:x="<<x<<",y="<<y<<endl;
 return 0;
}
结果为:

Befor swap:x=3,y=9

In swap,Begin:a=3,b=9

In swap,End:a=9,b=3

After swap:x=9,y=3

函数调用过程中形参和实参都发生了变化,这是因为形参是实参的别名的缘故。


最后再看一个可能很容易被判断为正确的例子:

void swap(int *a,int *b)

{

int *t;

*t=*a;

*a=*b;

*b=*t;

}

程序的main函数和上面各例子中的相同,这个程序编译和链接都是没有错误的,然而在运行时出错了!原因就在于swap函数中定义了一个指向整型变量的指针t,t没有初始化接下来就是用了*t来访问t所指向的存储单元的内容,这是很危险的!因为p很有可能指向的内存是非法的。

 

 

转载请注明出处:http://blog.csdn.net/collier/archive/2010/09/04/5862752.aspx

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值