回 帖 发 新 帖 刷新版面

主题:异或操作的式子,看不懂。求解释

a ^= b ^= a ^= b;
书上说这个式子可以交换a和b的值。
我知道异或怎么算,如果我一步一步分开来,并给a,b都假定一个值,我是可以算出结果确实是交换了两个值,可是我不明白这样写连起来的道理,就是我不清楚为什么别人能想到这么写?

书上是这么解释的:可以将上述等效于下述两步:
b = b ^= a ^= b; a = a ^= b;//这里就看不懂了。

回复列表 (共13个回复)

沙发

a ^= b;
b ^= a; // 这一句就等于 b = b^a^b,也就是 b = a;
a ^= b; // 这一句就等于 a = a^b^b,也就是 a = b;
// 注释中的a,b都是指原先的值

板凳

这个式子从右往左算显示a^b的值赋给a,然后a^b的值赋给b,然后a^b的值赋给a.有四种情况,列个表说明
      情况1  情况2  情况3  情况4
    a      0        1         0        1             
    b      1        1         0        0                 
    a      1        0         0        1                
    b      0        1         0        1               
    a      1        1         0        0
表中是每两行进行异或的值赋给下一行
最后发现四种情况都能实现a,b的交换
但是为什么别人能想到这么写,我也不清楚了,反正我是想不到的

3 楼

a^=b;
b^=a;
a^=b;
这是标准转换过程,如果我们注意到a^=b表达式返回的是a,则前两句就可以连在一起写。
b^=(a^=b);
而赋值表达式是右结合的,所以括号可以省掉。

以此类推,这样我们就可以得到:
a^=b^=a^=b;
了:)

4 楼

其实也可以从逻辑上来理解,假如ab不同,将1赋给a,b与1异或取反,也就是将b变成a,然后再与1异或取反赋给a,也就是a得到原来的b值;假如ab相同,则将0赋给a,b与0异或保持原值不变,在与0异或保持原值赋给a.所以相当于都实现了a与b的交换.

5 楼

呵呵,学习了~

6 楼

[quote]但是为什么别人能想到这么写,我也不清楚了,反正我是想不到的[/quote]
我觉得这种写法的效率应该没使用临时变量高,并且不好懂。

7 楼

或是这样理解:
a^b=b^a

a^b^b=a

故:
a^b^a=b^a^a=b

根据上面的结论,我们做如下推导:
设原a,b值为a,b
新a,b值为an,bn
a^=b: 
  an
 =a^b;

b^=a:
  bn
 =an^b
 =a^b^b
 =a;

a^=b:
  an
 =bn^an
 =a^an
 =a^a^b
 =b;

8 楼

[quote][quote]但是为什么别人能想到这么写,我也不清楚了,反正我是想不到的[/quote]
我觉得这种写法的效率应该没使用临时变量高,并且不好懂。[/quote]嘿嘿,特殊情况下会比较可行,比如两个都在寄存器里的时候:)

9 楼

呵呵,都在寄存器里,直接xchg(好像叫这个,记不清了)指令了。

10 楼

[quote]呵呵,都在寄存器里,直接xchg(好像叫这个,记不清了)指令了。[/quote]
是这个,不过精减指令集的CPU是没有这个的,这个仅存在于x86和复杂指令集的CPU中:)

我来回复

您尚未登录,请登录后再回复。点此登录或注册