下面5个函数哪个能够成功进行两个数的交换?
#include <iostream>
using namespace std;
void swap1(int p, int q)
{
int temp;
temp = p;
p = q;
q = temp;
}
void swap2(int *p, int *q)
{
int *temp;
*temp = *p;
*p = *q;
*q = *temp;
}
void swap3(int *p, int *q)
{
int *temp;
temp = p;
p = q;
q = temp;
}
void swap4(int *p, int *q)
{
int temp;
temp = *p;
*p = *q;
*q = temp;
}
void swap5(int &p, int &q)
{
int temp;
temp = p;
p = q;
q = temp;
}
int main( )
{
int a = 1, b = 2;
// swap1(a, b);
// swap2(&a, &b);
// swap3(&a, &b);
// swap4(&a, &b);
// swap5(a, b);
cout << a << " " << b << endl;
return 0;
}
答案:只有swap4函数和swap5函数能够实现。
解析:
(1)swap1传的是值的副本,在函数体内被修改了形参p、q(实际参数a、b的一个拷贝),p、q的值确实交换了,但是它们是局部变量,不会影响到主函数中的a和b。当函数awap1生命周期结束后,p、q所在栈也就被删除了。
(2)swap2传的是一个地址进去,在函数体内的形参*p、*q是指向实际参数a、b地址的两个指针。此处要注意:
int *temp;
*temp = *q;
是不符合逻辑的一段代码,int *temp 新建了一个指针(但没有分配内存)。*temp = *p 不是指向,而是拷贝。把*p 所指向的内存里的值(也就是实参a的值)拷贝到*temp所指向内存里了,但是 int *temp 不是不分配内存吗?的确不分配,于是系统在拷贝时,临时给了一个随机地址,让它存值。分配的随机地址是个”意外”,函数结束后不回收,造成内存泄漏。
那么swap2能否实现两数交换?这要视编译器而定,有的可以通过测试,有的更加“严格”的编译器如vs2010,这段代码会报错。
(3)swap3传的是一个地址进去,在函数体内的形参*p、*q是指向实际参数a、b地址的两个指针。这里要注意:
int *temp;
temp = p;
int *temp 新建了一个指针(但没有分配内存)。temp = p 是指向,而不是拷贝。temp 指向了 *p 所指向的地址(也就是a)。而代码:
p = q;
q = temp;
意思是p指向了*q所指向的地址(也就是b)。q指向了*t所指向的地址(也就是a)。
但是,swap3不能实现两数的交换,这是因为函数体内只是指针的变化,而对地址中的值却没有改变。
(4)swap4可以实现两数的交换,因为它修改的是指针所指向地址中的值。
(5)swap5和swap4类似,是一个引用传递,修改的结果直接影响实参。