可能重复:
Potential Problem in “Swapping values of two variables without using a third variable”
我最近在社区中读到,我们可以轻松地交换两个数字,而不使用第三个使用XOR技巧。
立方公尺= N ^ =立方公尺= N;提到了诀窍。
你们觉得怎么样?这个技巧总是有用吗?
答案 0 :(得分:5)
你写它的方式,它是未定义的行为。这是因为您在同一序列点中多次修改变量。但是,如果您按如下方式重写它:
m ^= n;
n ^= m;
m ^= n;
那么它是安全的。然而,“有用”是另一个问题,它很少“有用”,有时它实际上比实际使用临时更慢!
此外,你需要小心别名(指针/引用),因为如果你试图与自己交换东西,那么你最终会意外地将你的值归零。例如:
#define SWAP(m, n) { m ^= n; n ^= m; m ^= n; }
int x[] = { 1, 2, 3, 4 };
int i = 0;
int j = 0;
SWAP(x[i], x[j]); // whoops, x[0] == 0 now, not 1!
更传统的交换实现没有这个问题。
答案 1 :(得分:3)
不,它在C和C ++中都是未定义的行为。它有时可能会起作用,但你不应该依赖它。
即使是“固定”变体也不总是有效:
m ^= n;
n ^= m;
m ^= n;
如果m和n是对同一变量的引用,则会失败。在这种情况下,它将值设置为零。
C没有引用,但即使在C中,如果你试图使用这个技巧,仍然存在潜伏危险:
您可以尝试扩展技巧以交换数组中的两个值,但如果您使用相同的索引,这可能会失败:
a[m] ^= a[n];
a[n] ^= a[m];
a[m] ^= a[n];
现在,如果m == n,则再次将[m]的值设置为零。
请不要使用这样的“聪明”技巧。使用临时变量来交换两个值。
答案 2 :(得分:1)
通过该技巧,您可以节省额外的内存位置以保存临时值。 它可能对整数有效,但是可读吗?您的上一代优化器也可以这样做。
答案 3 :(得分:0)
这通常更具危险性(在您的情况下,它实际上是未定义的行为;加上如果一个数字为零,则出现问题)。除非你的内存严重不足,否则最好只使用临时变量(或stl交换函数)。这更清楚你正在做什么,更容易维护。