来源:公众号【编程珠玑】
作者:守望先生
ID:shouwangxiansheng
C语言交换两个整型变量,你有哪些方法?那么多方法,又有哪几个可行?
不可行的方法
初学者最容易理解错的方法:
//来源:公众号【编程珠玑】
//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;
}
不理解为何不行的请参考《传值与传指针》。
理解实参只是原数据的一个拷贝,非常关键。
可行方法
这里最容易想到的一种方法:
//来源:公众号【编程珠玑】
//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;
}
但是有人还试图用类似的方法交换字符串,那就不可取了:
//来源:公众号【编程珠玑】
//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的内容?还是参考《传值与传指针》。
不借助临时变量一
//来源:公众号【编程珠玑】
//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);
}
不过这个方法的缺点非常明显,那就是存在溢出的风险。
还有下面这种类似的方法:
void swap(int *a,int *b)
{
*a = *a * *b;
*b = *a / *b;
*a = *a / *b;
}
这种方法除了有溢出风险外,b还不能为0。
不借助临时变量二
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 |
不过这种方法中,如果传入参数指向同一地址,它并不如预期那样工作:
//来源:公众号【编程珠玑】
//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;
}
至于前面提到的不借助第三个变量的方法,你都可以尝试一下,它可能不如你预期那样工作奥!
既然如此,可以稍微改进一下:
void swap(int *a,int *b)
{
if(a != b)
{
*a = *a ^ *b;
*b = *a ^ *b;
*a = *a ^ *b;
}
}
总结
那么问题来了,那种方式更快呢?
答案可能让你意外:
在编译器的优化下,使用临时变量的方式可能是最快的。
你还有什么方法交换两个整数的值?欢迎留言。
#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;
}