方法一:引入中间变量tmp。
(需要引入中间变量,需要开辟空间)
函数代码如下:
void swap1(int *a ,int *b)//引入中间变量tmp
{
int tmp = *a;
*a = *b;
*b = tmp;
}
方法二:加减运算法。
(加法可能产生数值溢出情况,整形最多只能表示32位二进制数)
函数代码如下:
void swap2(int *a,int *b)//加减运算法
{
*a = *a + *b;
*b = *a - *b;
*a = *a - *b;
}
方法三:取模法。
(需要引入中间变量,需要开辟空间)
函数代码如下:
void swap3(int *a, int *b)//取模法
{
int c = *a % *b;
*a = *b;
*b = c;
}
方法四:异或法。
(不需要引入中间变量,不需要开辟空间),是比较推荐的一种算法。
函数代码如下:
void swap4(int *a, int *b)//异或法
{
*a ^= *b;
*b ^= *a;
*a ^= *b;
}
方法五:乘除法。
(乘法也可能产生数值溢出情况)
函数代码如下:
void swap5(int *a, int *b)//乘除法
{
*a = *a * (*b);
*b = *a / *b;
*a = *a / *b;
}
方法六:位运算法。
介绍一种高逼格的方法,很少人会想到。int64表示64位整型变量。
b = (int64)((int64)a << 32 | (a = b)) >> 32;
这个语句中a=b为把b的值赋给a。整个语句的意思:先把a强制转化为64位整型变量,然后把它左移32位后与(a=b)按位或,把整个结果再强制转换为64位整型变量,然后右移32位得到b的值。其实,求b的值没必要有|(a=b)这部分,但因为想同时把b的值赋给a,且把|(a=b)放在这儿不会影响到b最终的值,所以写成这样。这儿就采用移位的方法避免了用中间变量。
但上面的式子有点问题:式子中第二个a的值可能来自原始的a,也有可能来自式子中第一个a。我们这里需要它是原始a的值。导致我第一次运行时发生错误,找了半天。改进的办法如下:
int x = a;
b = (int64)((int64)x << 32 | (a = b)) >> 32;
函数代码如下:
void swap6(int *a, int *b)
{
int x = *a;
*b = ((int64)((int64)x) << 32 | (*a = *b)) >> 32;
}
如果觉得上面一行代码看不懂,我们可以拆开来看:
int64 x = (int64)a << 32;
a = b;
x |= a;
b = x >> 32;
主函数代码如下:
#include<stdio.h>
#include<windows.h>
#pragma warning (disable : 4996 )
int main()
{
int a = 0;
int b = 0;
printf("请输入两个数:");
scanf("%d %d", &a, &b);
printf("a = %d; b = %d\n", a, b);
swap1(&a, &b);
printf("a = %d; b = %d\n", a, b);
system("pause");
}
另外说明一下:
#pragma warning (disable : 4996 )
#define _CRT_SECURE_NO_WARNINGS 1
VS2013编译器运行过程中遇到scanf函数会产生安全警告⚠️
这两条语句为了消除这种安全警告⚠️