C语言如何交换两个整型的值?

C语言交换两个整型变量,你有哪些方法?那么多方法,又有哪几个可行?

不可行的方法

初学者最容易理解错的方法:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
//来源:公众号【编程珠玑】
//https://www.yanbinghu.com
#include<stdio.h>
void swap(int a,int b)
{
int temp = a;
a = b;
b = temp;
}
int main(void)
{
int a = 10;
int b = 24;
swap(a,b);
//输出a = 10,b = 20
printf("a = %d,b = %d\n",a,b);
return 0;
}

不理解为何不行的请参考《传值与传指针》。

理解实参只是原数据的一个拷贝,非常关键。

可行方法

这里最容易想到的一种方法:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
//来源:公众号【编程珠玑】
//https://www.yanbinghu.com
#include<stdio.h>
void swap(int *a,int *b)
{
int temp = *a;
*a = *b;
*b = temp;
}
int main(void)
{
int a = 10;
int b = 24;
swap(&a,&b);
//输出a = 24,b = 10
printf("a = %d,b = %d\n",a,b);
return 0;
}

但是有人还试图用类似的方法交换字符串,那就不可取了:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
//来源:公众号【编程珠玑】
//https://www.yanbinghu.com
#include<stdio.h>
void swap(char *a,char *b)
{
char *temp = a;
a = b;
b = temp;
}
int main(void)
{
char a[] = "hello";
char b[] = "world";
swap(a,b);
//输出a = hello,b = world
printf("a = %s,b = %s\n",a,b);
return 0;
}

什么?为什么没有像你预期那样交换a和b的内容?还是参考《传值与传指针》。

不借助临时变量一

1
2
3
4
5
6
7
8
9
10
11
//来源:公众号【编程珠玑】
//https://www.yanbinghu.com
#include<stdio.h>
void swap(int *a,int *b)
{
*a = *a + *b; //10 + 24 = 34 ,有溢出的风险
*b = *a - *b; //34 - 24 = 10
*a = *a - *b; //34 - 10 = 24
//变体如下:
//*a = (*a + *b) - (*b = *a);
}

不过这个方法的缺点非常明显,那就是存在溢出的风险。

还有下面这种类似的方法:

1
2
3
4
5
6
void swap(int *a,int *b)
{
*a = *a * *b;
*b = *a / *b;
*a = *a / *b;
}

这种方法除了有溢出风险外,b还不能为0。

不借助临时变量二

1
2
3
4
5
6
7
8
void swap(int *a,int *b)
{
*a = *a ^ *b;
*b = *a ^ *b;
*a = *a ^ *b;
//变体如下
//*a = (*a ^ *b) ^ (*b ^ *a);
}

没错,就是采用异或,相同异或(0^0=0;1^1=0)结果为0,不同异或(0^1 = 1)结果为1。

a = a ^ *b:

0 1 0 1 0 a = 10
1 1 0 0 0 b = 24
1 0 0 1 0 a = a ^ b = 18

b = a ^ *b:

1 0 0 1 0 a = 18
1 1 0 0 0 b = 24
0 1 0 1 0 b = a ^ b = 10

a = a ^ *b:

1 0 0 1 0 a = 18
0 1 0 1 0 b = 10
1 1 0 0 0 a = a ^ b = 24

不过这种方法中,如果传入参数指向同一地址,它并不如预期那样工作:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
//来源:公众号【编程珠玑】
//https://www.yanbinghu.com
#include<stdio.h>
void swap(int *a,int *b)
{
*a = *a ^ *b;
*b = *a ^ *b;
*a = *a ^ *b;
}
int main(void)
{
int a = 10;
swap(&a,&a);//都传入a
//输出a = 0
printf("a = %d\n",a);
return 0;
}

至于前面提到的不借助第三个变量的方法,你都可以尝试一下,它可能不如你预期那样工作奥!

既然如此,可以稍微改进一下:

1
2
3
4
5
6
7
8
9
void swap(int *a,int *b)
{
if(a != b)
{
*a = *a ^ *b;
*b = *a ^ *b;
*a = *a ^ *b;
}
}

总结

那么问题来了,那种方式更快呢?

答案可能让你意外:
在编译器的优化下,使用临时变量的方式可能是最快的。

你还有什么方法交换两个整数的值?欢迎留言。

1
2
3
4
5
6
7
8
9
#include<iostream>
int main()
{
std::string a = "10";
std::string b = "24";
std::swap(a,b);
std::cout<<"a="<<a<<";b="<<b<<std::endl;
return 0;
}
守望 wechat
关注公众号[编程珠玑]获取更多原创技术文章
出入相友,守望相助!