2010-10-03 64 views
0

可能重复:
Potential Problem in “Swapping values of two variables without using a third variable”这个技巧总是有效吗?

我最近在一个社区,我们可以很容易地交换两个号码,而无需使用第三方使用XOR招读取。

m^= n^= m^= n;提到了诡计。

你们认为什么?这个技巧总是有用吗?

+2

不,它没有。在这里你去:http://stackoverflow.com/questions/3741440/potential-problem-in-swapping-values-of-two-variables-without-using-a-third-vari/3741450 – codaddict 2010-10-03 08:22:16

回答

0

它往往更危险(在你的情况下,它实际上是未定义的行为;再加上如果一个数字为零,事情就会出错)。除非你的内存不足,否则最好只使用一个临时变量(或stl swap函数)。这更清楚你正在做什么,更容易维护。

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! 

更传统的swap实现没有这个问题。

3

不,它在C和C++中都是未定义的行为。它有时可能有效,但你不应该依赖它。

而且即使是“固定”的变化并不总是工作:

m ^= n; 
n ^= m; 
m ^= n; 

此,如果m和n相同的变量引用失败。在这种情况下,它将该值设置为零。

C没有引用,但即使使用C仍存在潜伏的危险,如果您尝试使用这种伎俩:

  • 您可以尝试把“工作”版本到宏SWAP,但如果使用SWAP(x,x)进行调用,则可能会失败,并将x始终设置为零。
  • 您可以尝试的伎俩延伸到阵列中的交换两个值,但如果再次使用相同的索引这可能失败:

    a[m] ^= a[n]; 
    a[n] ^= a[m]; 
    a[m] ^= a[n]; 
    

现在如果M ==ñ再次值的[m]被设置为零。

请不要使用这样的“聪明”技巧。使用临时变量交换两个值。

1

有了这个技巧,你可以保存一个额外的内存位置来保存一个临时值。 它可能对整数有效,但它是可读的吗?您的上一代优化器可能也会这样做。

+0

现代CPU的做得更好临时。他们可以并行执行这两个任务,但他们必须停止XOR版本。 – GManNickG 2010-10-03 08:47:02

+0

@GMan:你的意思是指导配对?但在这种情况下可以配对哪些作业? – 2010-10-03 09:05:06

+0

@Nick:With'int temp = x; x = y; y = temp;',后两者。 – GManNickG 2010-10-03 09:20:42