主题:异或操作的式子,看不懂。求解释
乖乖的上帝
[专家分:0] 发布于 2011-05-11 14:58:00
a ^= b ^= a ^= b;
书上说这个式子可以交换a和b的值。
我知道异或怎么算,如果我一步一步分开来,并给a,b都假定一个值,我是可以算出结果确实是交换了两个值,可是我不明白这样写连起来的道理,就是我不清楚为什么别人能想到这么写?
书上是这么解释的:可以将上述等效于下述两步:
b = b ^= a ^= b; a = a ^= b;//这里就看不懂了。
回复列表 (共13个回复)
沙发
bruceteen [专家分:42660] 发布于 2011-05-11 20:32:00
a ^= b;
b ^= a; // 这一句就等于 b = b^a^b,也就是 b = a;
a ^= b; // 这一句就等于 a = a^b^b,也就是 a = b;
// 注释中的a,b都是指原先的值
板凳
killergsm [专家分:90] 发布于 2011-05-13 10:24:00
这个式子从右往左算显示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 楼
cgl_lgs [专家分:21040] 发布于 2011-05-13 11:38:00
a^=b;
b^=a;
a^=b;
这是标准转换过程,如果我们注意到a^=b表达式返回的是a,则前两句就可以连在一起写。
b^=(a^=b);
而赋值表达式是右结合的,所以括号可以省掉。
以此类推,这样我们就可以得到:
a^=b^=a^=b;
了:)
4 楼
killergsm [专家分:90] 发布于 2011-05-13 12:14:00
其实也可以从逻辑上来理解,假如ab不同,将1赋给a,b与1异或取反,也就是将b变成a,然后再与1异或取反赋给a,也就是a得到原来的b值;假如ab相同,则将0赋给a,b与0异或保持原值不变,在与0异或保持原值赋给a.所以相当于都实现了a与b的交换.
5 楼
Pony279 [专家分:10] 发布于 2011-05-13 13:01:00
呵呵,学习了~
6 楼
windy0will [专家分:2300] 发布于 2011-05-13 13:41:00
[quote]但是为什么别人能想到这么写,我也不清楚了,反正我是想不到的[/quote]
我觉得这种写法的效率应该没使用临时变量高,并且不好懂。
7 楼
cgl_lgs [专家分:21040] 发布于 2011-05-13 13:45:00
或是这样理解:
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 楼
cgl_lgs [专家分:21040] 发布于 2011-05-13 13:48:00
[quote][quote]但是为什么别人能想到这么写,我也不清楚了,反正我是想不到的[/quote]
我觉得这种写法的效率应该没使用临时变量高,并且不好懂。[/quote]嘿嘿,特殊情况下会比较可行,比如两个都在寄存器里的时候:)
9 楼
windy0will [专家分:2300] 发布于 2011-05-13 13:54:00
呵呵,都在寄存器里,直接xchg(好像叫这个,记不清了)指令了。
10 楼
cgl_lgs [专家分:21040] 发布于 2011-05-13 13:58:00
[quote]呵呵,都在寄存器里,直接xchg(好像叫这个,记不清了)指令了。[/quote]
是这个,不过精减指令集的CPU是没有这个的,这个仅存在于x86和复杂指令集的CPU中:)
我来回复