【问题标题】:A ^= B ^= A ^= B; unexpected result in c# visual studio [duplicate]A ^= B ^= A ^= B; c#visual studio中的意外结果[重复]
【发布时间】:2017-12-06 02:16:01
【问题描述】:

我一直认为 A ^= B ^= A ^= B 交换 A B。我猜这条线应该分 3 步从右到左进行评估:

1) A ^= B;
2) B ^= A;
3) A ^= B;

但是在 C# 中,如果你在一行中执行,A 会以某种方式变为 0。我查看了程序集,发现原始 A 被首先存储,并且在最后第三步中以某种方式存储,而不是获取 A 的实际当前值,代码使用缓存的原始值。组装看起来像这样:

mov         eax,dword ptr [ebp-40h]  //eax <- A
mov         dword ptr [ebp-7Ch],eax  //C <- A (why cache?)
mov         eax,dword ptr [ebp-44h]  //eax <- B
xor         dword ptr [ebp-40h],eax  //A ^= B
mov         eax,dword ptr [ebp-40h]  //eax <- A
xor         dword ptr [ebp-44h],eax  //B ^= A
mov         eax,dword ptr [ebp-7Ch]  //eax <- C (?)
xor         eax,dword ptr [ebp-44h]  //eax ^= B (= C ^ B)
mov         dword ptr [ebp-40h],eax  //A = C ^ B (instead of A ^ B)

在 C++ 中似乎没问题,并且程序集只使用 2 个变量:

mov         eax,dword ptr [a]
xor         eax,dword ptr [b]
mov         dword ptr [a],eax
mov         ecx,dword ptr [b]
xor         ecx,dword ptr [a]
mov         dword ptr [b],ecx
mov         edx,dword ptr [a]
xor         edx,dword ptr [b]
mov         dword ptr [a],edx

我错过了什么吗?

【问题讨论】:

  • 不知道 C#,但可能相关:stackoverflow.com/q/38421671/3002139
  • 出于好奇:该代码有实际应用吗?
  • 好吧,没有理由这样做。有一次我想在代码面试中显得很花哨,我在一篇论文上写了那个交换。多年后,我在代码中实际尝试了它,只是为了看看我是否做对了。

标签: c# c++ visual-studio visual-studio-2017


【解决方案1】:

在 C++ 中,这将是一个未定义的行为*,因为有多个未排序的赋值。

在 C# 中这是完全有效的,零是正确的结果。

要了解为什么考虑将任何数字与自身进行异或运算会产生零,因为在位模式中的每个运动中都有相等的位。此外,XOR 顺序并不重要。这就是为什么 B 以 A 的旧值结束,而 A 最终为零的原因。

* 在 C++ 17 之前,无论如何。

【讨论】:

  • 好的,谢谢大家。我搜索得很糟糕。问题已经回答了。对不起
  • 在 C++17 中,围绕赋值更改了排序规则,因此请谨慎对待您的声明。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-07-15
  • 2016-02-23
  • 2011-10-20
  • 1970-01-01
  • 1970-01-01
  • 2021-10-06
相关资源
最近更新 更多