C语言用异或的方法将两个数的值互换
一、简单介绍
这里介绍用异或的方法实现互换两个数的值,无需借助第3个临时变量。对于给定两个整数a,b,下面的异或运算可以实现a,b的交换:
a = a ^ b;
b = a ^ b;
a = a ^ b;
核心思想:
1.任意一个变量a与其自身进行异或运算,结果为0,即a^a=0
2.任意一个变量a与0进行异或运算,结果不变,即a^0=a
3.异或运算具有可结合性,即a^b^c=(a^b)^c=a^(b^c)
4.异或运算具有可交换性,即a^b=b^a
a = a ^ b;
b = a ^ b;
a = a ^ b;
核心思想:
1.任意一个变量a与其自身进行异或运算,结果为0,即a^a=0
2.任意一个变量a与0进行异或运算,结果不变,即a^0=a
3.异或运算具有可结合性,即a^b^c=(a^b)^c=a^(b^c)
4.异或运算具有可交换性,即a^b=b^a
二、实例测试
#include <stdio.h>
#define swap(a,b) a^=b^=a^=b
int main(void)
{
int a=100,b=999;
int array[]={520,111};
printf("before swapping,a=%d,b=%d\n",a,b);
printf("before swapping,array[0]=%d,array[1]=%d\n",array[0],array[1]);
swap(a,b);
array[0]^=array[1];
array[1]^=array[0];
array[0]^=array[1];
printf("after swapping,a=%d,b=%d\n",a,b);
printf("after swapping,array[0]=%d,array[1]=%d\n",array[0],array[1]);
swap(array[0],array[1]);
printf("\narray[0]=%d,array[1]=%d\n",array[0],array[1]);
return 0;
}
2、gcc编译运行结果
四、运行结果分析。
在VC和GCC编译器,a和b的值都互换了,但数组array[0]和array[1]在gcc编译器array[0]得到的是一个莫名其妙的0值,很令人费解。那么原因是什么呢?因为C++语言没有在同一表达式中规定运算顺序,对于同一变量的两次修改不能放在一个表达式里,所以在第二次更改同一变量时不能保证取到的结果是第一次修改之后的。语言没有规定,那么行为就是未定义的。没有定义,是指不同编译器会出现不一样的行为,同一编译器也会出现不一样的行为。顺序是由编译器自行决定的,它可能对这组数据采用这种顺序,对另一组数据采用另一种顺序。不同编译器的实现不同,出现的结果也会不同。
具体解释如下:
a = 1 = 0001
b = 2 = 0010
a^=b^=a^=b; //对a修改了两次
先执行 a^=b
a = 0011
再执行 b^=a
b = 0001
最后执行a^=b,即 a = a^b
这里的a不一定会取到第一次修改后的0011,也可能取到第一次修改之前的0001,如果取修改之后的,则 a=0011^0001 = 2;如果取修改之前的,则 a=0001^0001 = 0;所以gcc和vc编译器的结论有所不同。
a = 1 = 0001
b = 2 = 0010
a^=b^=a^=b; //对a修改了两次
先执行 a^=b
a = 0011
再执行 b^=a
b = 0001
最后执行a^=b,即 a = a^b
这里的a不一定会取到第一次修改后的0011,也可能取到第一次修改之前的0001,如果取修改之后的,则 a=0011^0001 = 2;如果取修改之前的,则 a=0001^0001 = 0;所以gcc和vc编译器的结论有所不同。
五、用宏#define swap(a,b) a^=b^=a^=b 需要谨慎,最好分为3个表达式或者用#define swap(a,b) (a^=b,b^=a,a^=b)。
那就顺便试一下吧
测试代码:
#include <stdio.h>
#define swap(a,b) (a^=b,b^=a,a^=b)
int main(void)
{
int a=100,b=999;
int array[]={520,111};
printf("before swapping,a=%d,b=%d\n",a,b);
printf("before swapping,array[0]=%d,array[1]=%d\n",array[0],array[1]);
swap(a,b);
array[0]^=array[1];
array[1]^=array[0];
array[0]^=array[1];
printf("after swapping,a=%d,b=%d\n",a,b);
printf("after swapping,array[0]=%d,array[1]=%d\n",array[0],array[1]);
swap(array[0],array[1]), printf("\narray[0]=%d,array[1]=%d\n",array[0],array[1]);
return 0;
}
测试ok。记住用#define swap(a,b) (a^=b,b^=a,a^=b)