目录
前言:
在C++中,交换两个值是常见的操作之一。本文将详细介绍八种常用的交换方法,包括掩耳盗铃法、中间变量交换法、加减法、乘除法、异或交换法、使用STL中的swap
函数、指针传参法以及引用传参法。
1.掩耳盗铃法:
#include<iostream>
using namespace std;
int main()
{
int a=1, b=2;
cout << "交换前:" << endl;
cout << "a = " << a << ',';
cout << "b = " << b << endl;
cout << "交换后:" << endl;
cout << "a = " << b << ',';
cout << "b = " << a << endl;
return 0;
}
运行结果:
交换前:
a = 1,b = 2
交换后:
a = 2,b = 1
一种娱乐写法,这种方法虽然看似交换了两个变量的值,但实际上并没有真正交换它们,实战慎用。
2.中间变量交换法:
#include<iostream>
using namespace std;
int main()
{
int a = 1,b = 2;
cout << "交换前:" << endl;
cout << "a = " << a << ',';
cout << "b = " << b << endl;
int temp = a;
a = b;
b = temp;
cout << "交换后:" << endl;
cout << "a = " << a << ',';
cout << "b = " << b << endl;
return 0;
}
运行结果:
交换前:
a = 1,b = 2
交换后:
a = 2,b = 1
这种方法通过引入一个临时变量来交换两个变量的值。具体步骤如下:
- 将 a 的值赋给临时变量 temp。
- 将 b 的值赋给 a。
- 将的值 temp(即原来的 a 的值)赋给 b。
这样,a 和 b 的值就完成了交换。
3.加减法:
#include<iostream>
using namespace std;
int main()
{
int a = 1, b = 2;
cout << "交换前:" << endl;
cout << "a = " << a << ',';
cout << "b = " << b << endl;
a = a + b;
b = a - b;
a = a - b;
cout << "交换后:" << endl;
cout << "a = " << a << ',';
cout << "b = " << b << endl;
return 0;
}
运行结果:
交换前:
a = 1,b = 2
交换后:
a = 2,b = 1
这种方法通过数学加减法运算来交换两个变量的值,而不需要使用额外的临时变量。具体步骤如下:
- 将 a 的值加上 b 的值,并将结果赋给 a。
- 将 a 的新值减去 b 的值,并将结果赋给 b。
- 再次将 a 的值减去 b 的新值,并将结果赋给 a。
这样, a 和 b 的值就完成了交换。
4.乘除法:
#include<iostream>
using namespace std;
int main()
{
int a = 1, b = 2;
cout << "交换前:" << endl;
cout << "a = " << a << ',';
cout << "b = " << b << endl;
a = a * b;
b = a / b;
a = a / b;
cout << "交换后:" << endl;
cout << "a = " << a << ',';
cout << "b = " << b << endl;
return 0;
}
运行结果:
交换前:
a = 1,b = 2
交换后:
a = 2,b = 1
注意:使用这种方法时要注意溢出、零除等情况。
这种方法通过数学乘除法运算来交换两个变量的值,而不需要使用额外的临时变量。具体步骤如下:
- 将 a 的值乘上 b 的值,并将结果赋给 a。
- 将 a 的新值除去 b 的值,并将结果赋给 b。
- 再次将 a 的值除去 b 的新值,并将结果赋给 a。
这样, a 和 b 的值就完成了交换。
5.异或交换法:
一篇位运算讲解非常透彻的博客:位运算全面总结,关于位运算看这篇就够了
#include<iostream>
using namespace std;
int main()
{
int a = 1, b = 2;
cout << "交换前:" << endl;
cout << "a = " << a << ',';
cout << "b = " << b << endl;
a = a ^ b;
b = a ^ b;
a = a ^ b;
cout << "交换后:" << endl;
cout << "a = " << a << ',';
cout << "b = " << b << endl;
return 0;
}
运行结果:
交换前:
a = 1,b = 2
交换后:
a = 2,b = 1
异或交换法是一种利用位运算中的异或(XOR)操作来交换两个整数变量值的方法,它不需要额外的临时变量。这种方法背后的逻辑基于异或运算的一些性质:
- 任何数与自身异或等于0:x ^ x = 0
- 任何数与0异或等于其本身:x ^ 0 = x
- 异或运算是可交换和结合的:a ^ b = b ^ a 和 a ^ (b ^ c) = (a ^ b) ^ c
现在我们来详细地看一下异或交换法的工作原理:
- a = a ^ b。
- b = a ^ b,由第一步得a = a ^ b;可将式子转化为b = (a ^ b) ^ b,利用上面的第三条性质得:b = a ^ (b ^ b),利用第一条性质得:b = a ^ 0,再利用第二条性质得:b = a。
- a = a ^ b,由第一步及第二步得a = a ^ b,b = a,可将式子等价代换为a = (a ^ b) ^ a,利用第三条性质得:a = (a ^ a) ^ b,利用第一条性质得:a = 0 ^ b,再利用第二条性质得:a = b。
6.使用STL中的swap函数交换(永远的神!!!):
#include<iostream>
#include<utility>
//#include <algorithm>
using namespace std;
int main()
{
int a = 1, b = 2;
cout << "交换前:" << endl;
cout << "a = " << a << ',';
cout << "b = " << b << endl;
swap(a, b);
cout << "交换后:" << endl;
cout << "a = " << a << ',';
cout << "b = " << b << endl;
return 0;
}
运行结果:
交换前:
a = 1,b = 2
交换后:
a = 2,b = 1
注意:该函数在 C++11 之前在 <algorithm> 头文件中,C++11 及之后在 <utility> 头文件中。
函数原型(普通版本):
template< class T >
void swap( T& a, T& b );
这种方法通过使用 C++ 标准库中的 std::swap
函数来交换两个变量的值,而不需要使用额外的临时变量,只需将两个参数放入函数中即可。
7.指针传参法:
在讲解指针传递法前,我们先看一下常见的手写 swap 函数的错误写法:
#include<iostream>
using namespace std;
void myswap(int a,int b)
{
int temp=a;
a=b;
b=temp;
}
int main()
{
int a = 1, b = 2;
cout << "交换前:" << endl;
cout << "a = " << a << ',';
cout << "b = " << b << endl;
myswap(a, b);
cout << "交换后:" << endl;
cout << "a = " << a << ',';
cout << "b = " << b << endl;
return 0;
}
运行结果:
交换前:
a = 1,b = 2
交换后:
a = 1,b = 2
通过运行结果我们可以看出 a 与 b 的值并没有交换。下面将详细解释一下原因:
在 C++ 中,默认的参数传递方式是传值(pass by value),这意味着函数接收的是变量的副本,而不是变量本身。因此,当调用 myswap(a,b) 时,a 和 b 的值被复制到 myswap 函数内部的局部变量 a 和 b 中。在 myswap 函数内部,虽然通过临时变量 temp 成功交换了这两个局部变量的值,但这些修改仅限于函数内部的副本,并不会影响到 main 函数中的原始变量 a 和 b 。
以下为解决办法:
解决办法1(不推荐):
在函数中直接输出结果
#include<iostream>
using namespace std;
void myswap(int a,int b)
{
int temp=a;
a=b;
b=temp;
cout << "交换后:" << endl;
cout << "a = " << a << ',';
cout << "b = " << b << endl;
}
int main()
{
int a = 1, b = 2;
cout << "交换前:" << endl;
cout << "a = " << a << ',';
cout << "b = " << b << endl;
myswap(a, b);
return 0;
}
运行结果:
交换前:
a = 1,b = 2
交换后:
a = 2,b = 1
解决办法1通过在 myswap 函数中使用中间变量 temp 来交换 a 和 b 的值,并直接在函数内部输出这两个变量的值。这种方式虽然能够实现两个整数的交换,但由于是在函数内部进行输出,因此只能看到交换后的结果,而无法在主函数中获取到交换后的值。这意味着如果需要在其他地方使用交换后的值,因此这种方法并不推荐。
解决办法2(不推荐):
定义全局变量
#include<iostream>
using namespace std;
int a = 1, b = 2;
void myswap()
{
int temp=a;
a=b;
b=temp;
}
int main()
{
cout << "交换前:" << endl;
cout << "a = " << a << ',';
cout << "b = " << b << endl;
myswap();
cout << "交换后:" << endl;
cout << "a = " << a << ',';
cout << "b = " << b << endl;
return 0;
}
运行结果:
交换前:
a = 1,b = 2
交换后:
a = 2,b = 1
解决办法2通过在 myswap 函数中使用全局变量 a 和 b 来实现两个整数的交换。这种方式虽然能够成功地交换两个整数的值,并且在主函数 main 中可以看到交换后的结果,但由于直接修改了全局变量,这可能会导致代码的可读性和维护性降低,因此这种方法并不推荐。
解决办法3(推荐):
不懂指针的可以去看这篇博客:C++指针(超详解)
使用该板块的主角:指针传参法
#include<iostream>
using namespace std;
void myswap(int* a, int* b)
{
int temp = *a;
*a = *b;
*b = temp;
}
int main()
{
int a = 1, b = 2;
cout << "交换前:" << endl;
cout << "a = " << a << ',';
cout << "b = " << b << endl;
myswap(&a, &b);
cout << "交换后:" << endl;
cout << "a = " << a << ',';
cout << "b = " << b << endl;
return 0;
}
运行结果:
交换前:
a = 1,b = 2
交换后:
a = 2,b = 1
解决办法3采用了指针传参的方法来实现两个整数的交换,在 main 函数中将需要交换两个整数 a 和 b 地址(即 &a 和 &b )传递给 myswap 函数,在 myswap 函数中利用解引用运算符(*
)访问指针所指向的内存位置并执行值的交换:
- int temp = *a,将 *a 的值赋给 temp 。
- *a = *b,将 *b 的值赋给 *a 指向的位置
- *b = temp,将 temp 的值赋给 *b 指向的位置
因为 myswap 函数直接操作的是 main 中变量 a 和 b 的内存地址,所以对这些地址处的值所做的任何更改都会反映在 main 中。因此,在调用 myswap(&a,&b) 之后,a 和 b 的值被正确且永久地交换,并且这种变化可以在 main 函数中看到,综上这种方法是比较推荐的方法。
8.引用传参法:
不懂引用的可以去看这篇博客:C++ 引用(&)的超详细解析(小白必看系列)
#include<iostream>
using namespace std;
void myswap(int& a, int& b)
{
int temp = a;
a = b;
b = temp;
}
int main()
{
int a = 1, b = 2;
cout << "交换前:" << endl;
cout << "a = " << a << ',';
cout << "b = " << b << endl;
myswap(a, b);
cout << "交换后:" << endl;
cout << "a = " << a << ',';
cout << "b = " << b << endl;
return 0;
}
运行结果:
交换前:
a = 1,b = 2
交换后:
a = 2,b = 1
解决办法3采用了引用传参的方法来实现两个整数的交换。在 main 函数中,将需要交换的两个整数 a 和 b 通过引用传递给 myswap 函数。在 myswap 函数中,直接操作这些引用所指向的变量值,从而完成值的交换:
int temp = a,
将引用 a 所指向的值(即 a 的值)赋给临时变量 temp 。a = b,
将引用 b 所指向的值(即 b 的值)赋给引用 a 所指向的位置(即 a 的位置)。b = temp,
将临时变量 temp 的值(即原来的 a 的值)赋给引用 b 所指向的位置(即 b 的位置)。
因为 myswap 函数直接操作的是 main 中变量 a 和 b 的内存地址,所以对这些地址处的值所做的任何更改都会反映在 main 中。因此,在调用 myswap(a,b)之后,a 和 b 的值被正确且永久地交换,并且这种变化可以在 main 函数中看到。
总结:
通过本文的介绍,相信大家对C++中交换两个值的八种常用方法有了全面的了解。每种方法都有其特点和适用场景,希望这些内容能帮助大家在实际编程中更加灵活地选择和应用,如果有不懂和发现问题的小伙伴,请在评论区说出来哦,如果本文对您有帮助,请点赞支持一下~