交换技巧:a=b+(b=a)*0;

本文关键字:交换 | 更新日期: 2023-09-27 18:04:46

a=b+(b=a)*0;

这个句子可以在a和b之间交换值。
我已经用c#试过了,它可以工作。
但我不知道这是怎么回事。
例如

a = 1, b = 2

我列出了它的步骤如下:

b = a -> a = 1, b = 1
b * 0 -> a = 1, b = 1
b + 0 -> a = 1, b = 1
a = b -> a = 1, b = 1 ?

但是b的值可能是错误的。
有人能帮我吗?这让我很困惑。

交换技巧:a=b+(b=a)*0;

a=b+(b=a)*0;

中间的(b=a)是一条赋值语句,将b设置为a的当前值,其副作用是其结果为b的最终值。当它乘以0时,得到0,但赋值仍然发生了。

外部位将a设置为b加上(b=a)*0的结果(为零)。因为在(b=a)位赋值之前,原来的b已经被用来开始设置a,所以这个赋值对a没有影响。换句话说,它是一个原子a = b; b = a;,交换两个值。

c#按照严格的从左到右的顺序计算(不像C和c++),以避免大量微妙的bug。请注意,编译器可以以不同的顺序计算它们,但前提是它可以确定它没有效果(这里不是这种情况)。

你发布的代码片段是有效的,但也是丑陋的,不是一个好主意,特别是当你可以使用更容易读的:

int t = a; a = b; b = t;

像你在这里看到的技巧,异或交换技巧,以及Duff的设备在体面的,可维护的代码中没有位置。它们通常是程序员展示他们有多聪明的一种方式,但它们通常只是显示他们有多坏。

如果你曾经在产品代码中看到类似的东西,我认为世界上没有任何陪审团会因为你追捕肇事者并用卷起来的程序清单把他们打死而定罪。

你应该写你的代码,好像下一个必须维护它的人是一个精神病患者,他知道你住在哪里——在我的情况下,你只对了一半——我不知道你住在哪里:-)

哎呀!你在哪里看到的?我比较习惯(a ^= b)B ^= a;a ^= b;)技巧,这样我至少能认出它(不要开枪!)我从来没说过我会用它!),但我得花点时间看看这个……如果你在产品代码中看到这种情况,请找出是谁写的,并伤害他。

正如其他人所说(但我想强调一下):"a = b"是一个赋值,但它也是一个带值的表达式。这就是为什么你可以做"a = b = c = d"这样的事情——这不是一个特殊的语言技巧;它们只是分组为"a = (b = (c = d))",而"d"的值折叠回所有这些变量

0. A =b+(b= A)*0 | | A = 1, b= 21. 求b | a=2+(b=a)*0 | a= 1, b= 22. 求(b=a) | a=2+1*0 | a= 1, b= 13.求1*0 | a=2+0 | a= 1, b = 14. 求2+0 | a=2 | a= 1, b = 15. 求a=2 | | a=2, b = 1