来源:公众号【编程珠玑】ios
做者:守望先生编程
ID:shouwangxiansheng优化
C语言交换两个整型变量,你有哪些方法?那么多方法,又有哪几个可行?指针
初学者最容易理解错的方法:code
//来源:公众号【编程珠玑】 //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; }
不理解为什么不行的请参考《传值与传指针》。字符串
理解实参只是原数据的一个拷贝,很是关键。get
这里最容易想到的一种方法:编译器
//来源:公众号【编程珠玑】 //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; }
可是有人还试图用相似的方法交换字符串,那就不可取了:string
//来源:公众号【编程珠玑】 //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的内容?仍是参考《传值与传指针》。io
//来源:公众号【编程珠玑】 //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; }