交换技巧:a=b+(b=a)*0;
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;
This sentence can swap the value between a and b.
I've tried it with C# and it works.
But I just don't konw how it works.
e.g.
a = 1, b = 2
I list the steps of it as below:
b = a -> a = 1, b = 1
b * 0 -> a = 1, b = 1
b + 0 -> a = 1, b = 1
a = b -> a = 1, b = 1 ?
But the value of b may be wrong.
Could anyone help me? It puzzles me a lot.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
中间的
(b=a)
是一个赋值语句,将b
设置为a
的当前值,其副作用是: (最终值)b
。当它乘以 0 时,得到 0,但赋值仍然发生。外部位将
a
设置为b
加上(b=a)*0
的结果(为零)。因为在(b=a)
位赋值之前,原来的b
已经被用来开始设置a
,所以赋值没有效果在a
上。换句话说,它是一个原子a = b; b = a;
,交换两个值。C# 按照严格的从左到右的顺序计算事物(与 C 和 C++ 不同),以避免大量微妙的错误。请注意,编译器可以以不同的顺序计算它们,但前提是它可以确定它不会产生任何影响(这里不是这种情况)。
您发布的代码片段可以工作,但也很丑陋,不是一个好主意,特别是当您可以使用更具可读性的时候:
像您在这里看到的技巧,以及 XOR 交换技巧,以及 Duff 的设备在体面的、可维护的中没有地位代码。它们通常是程序员展示他们有多聪明的一种方式,但它们通常只是展示他们有多么糟糕。
如果你在生产代码中看到类似的东西,我认为世界上任何陪审团都不会因为你追捕肇事者并用汇总的程序列表将他们打死而定罪。
你应该编写你的代码,就好像下一个必须维护它的人是一个知道你住在哪里的精神病患者一样 - 就我而言,你只对了一半 - 我不知道你住在哪里:-)
That
(b=a)
in the middle is an assignment statement settingb
to the current value ofa
with the side effect that its result is (the final value of)b
. When that's multiplied by 0, you get 0, but the assignment has still happened.The outer bit sets
a
tob
plus the result of(b=a)*0
(which is zero). Because the originalb
has already been used to start settinga
before the assignment in the(b=a)
bit, the assignment has no effect ona
. In other words, it's an atomica = b; b = a;
, swapping the two values.C# evaluates things in a strict left to right order (unlike C and C++) to avoid a large class of subtle bugs. Note that the compiler can evaluate them in a different order but only if it can determine that it will have no effect (that's not the case here).
The snippet you posted works, but is also hideous and not a good idea, especially when you can just use the far more readable:
Tricks like what you see here, and the XOR swap trick, and Duff's device have no place in decent, maintainable code. They're usually a way for coders to show how clever they are but they usually just show how bad they are.
If you ever see something like that in production code, I don't think any jury in the world would convict you for hunting down the perpetrator and beating them to death with the rolled up program listing.
You should write your code as if the next person that has to maintain it is a psychopath who knows where you live - in my case, you'd be half right - I have no idea where you live :-)
啊!你在哪里看到的?我相当习惯 (a ^= b; b ^= a; a ^= b;) 技巧,所以我至少认识到它(不要开枪!我从未说过我使用它!),但我必须看一下那个…如果你在生产代码中看到这个,请找出是谁写的并伤害了他。
正如其他人所说(但我想强调它):“a = b”是一个赋值,但它也是一个带有值的表达式。这就是为什么你可以做“a = b = c = d”这样的事情——这不是一个特殊情况的语言技巧;它们只是分组为“a = (b = (c = d))”,并且“d”的值折回到所有这些变量。
Ugh! Where did you see that?? I'm rather used to the (a ^= b; b ^= a; a ^= b;) trick, so that I at least recognize it (DON'T SHOOT! I NEVER SAID I USE IT!), but I'd have to look at that one for a minute... If you saw that in production code, please figure out who wrote it and hurt him.
As the others have said (but I'd like to emphasize it): "a = b" is an assignment, but it is also an expression with a value. That's why you can do things like "a = b = c = d" - it's not a special-case language trick; they just group as "a = (b = (c = d))", and the value of "d" folds back to all of those variables.