来源:公众号【编程珠玑】
作者:守望先生
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;
-
}
转载:https://blog.csdn.net/hyb612/article/details/103940306
查看评论