【发布时间】:2015-10-18 23:40:20
【问题描述】:
我遇到了一种“技术”,用于交换 2 个变量(整数、字符或指针)没有第三个临时变量,如下所示:
int a = Something ;
int b = SomethingElse ;
a ^= b ;
b ^= a ;
a ^= b ;
正常的方式是:
int a = Something ;
int b = SomethingElse ;
int temp = a ;
a = b ;
b = temp ;
这一切都很好,但分享这种“技术”的人通常将其声明为不使用额外空间。
(A) 没有多余的空间是真的吗?我认为,与“内存到内存 XOR 操作”相比,“内存到内存复制”需要更少的指令(机器代码)。
int temp = a <==> move content of memory location a to memory location temp **(1 instruction)**, possibly via a register **(2 instructions)**
a ^= b <==> move contents of memory location a to register1, move contents of memory location b to register2, xor register1 and register2 (store results in register1) , move register1 to memory location a **(about 4 instructions)**
似乎“技术”会导致更长的代码和更长的运行时间。
(B)“技术”在某些方面或某些情况下是否更快(或更好)?
似乎“技术”速度较慢,使用更多内存,并且不太适合浮点数。
编辑:
似乎可能有一些潜在的重复:
Why don't people use xor swaps?
但是这个问题明显不同:
(A) 该问题被关闭为“非建设性”,它“可能会引发辩论、争论、民意调查或扩展讨论”,而该问题正在寻找事实参考,例如“某事是真的吗?” &“这样更好吗?”
(B) 这个问题是关于为什么人们不使用“技术”,而这个问题是关于“技术”的分析,没有研究人们为什么使用还是不使用。
【问题讨论】:
-
@Prem 他们这样做是因为您还没有阅读“如何提问”,所以您会知道这不属于超级用户。 StackOverflow != 超级用户。
-
确实XOR交换通常没有意义,而且在机器代码中临时变量通常只是一个寄存器,所以它基本上是免费的。此外,大多数架构不能对内存进行 XOR,并且无论如何都必须将至少一个操作数加载到寄存器中。如果两者恰好都在寄存器中,则交换基本上是无操作的,只是编译器重新分配寄存器。
-
总而言之,这取决于CPU架构和编译器优化。通过编译器运行这两个变体,并比较输出。基本上能说的就这些了。至于代码的清晰度,实际上我更喜欢临时的。
-
无用的招数在更无用的求职面试官中流行。
-
根据this answer,编译器应该优化您的代码,因此XOR 没有任何改进。 this page 展示了如何使用这种技术和指针来交换任何类型的变量。