C++ 奇怪的交换宏

C++ 奇怪的交换宏,c++,C++,我输入了这些代码。然而,结果超出了我的预期 #define SWAP(x,y) {x=x^y;y=x^y;x=x^y;} #define SWAP2(x,y) {x=x+y;y=x-y;x=x-y;} int main() { int ia[] = { 1, 10, 1 }; SWAP(ia[0], ia[0]); // the resutl is ia[0] = 0 SWAP(ia[1], ia[2]); // work fine SWAP2(ia[1]

我输入了这些代码。然而,结果超出了我的预期

#define SWAP(x,y) {x=x^y;y=x^y;x=x^y;}
#define SWAP2(x,y) {x=x+y;y=x-y;x=x-y;}
int main()
{
    int ia[] = { 1, 10, 1 };
    SWAP(ia[0], ia[0]);   // the resutl is ia[0] = 0
    SWAP(ia[1], ia[2]);   // work fine
    SWAP2(ia[1], ia[1])   // the result is ia[0] = 0    
}
有人能帮我吗?任何帮助都将不胜感激。

第一次交换:

ia[0] = ia[0] ^ ia[0];
ia[0] = ia[0] ^ ia[0];
ia[0] = ia[0] ^ ia[0];
好的,任何值与其自身的XOR'd等于零。这就是为什么第一次交换导致ia[0]变为零。 第二个很好,所以我跳过它跳到第三个

ia[1] = ia[1] + ia[1];
ia[1] = ia[1] - ia[1];
ia[1] = ia[1] - ia[1];

ia[1]-ia[1]的结果是什么?无论ia[1]的值如何,始终为零。

第一次
交换
称为
异或交换
,它可以在没有临时变量的情况下交换两个不同的变量。但是,这两个变量必须有不同的地址。这就是交换的原因(ia[0],ia[0])失败,但
交换(ia[1],ia[2])工作正常

第二个
SWAP2
是危险的,因为
x+y
可能溢出。你不应该用那个

要使异或交换工作,您需要进行一些修改:

void swap(int &x, int &y) {
    if (&x != &y) {
        x ^= y;
        y ^= x;
        x ^= y;
    }
}

您的问题是,您的交换算法要求这两个参数是独立的内存块

正如LYF_HKN所指出的,当
x=y
时,每个算法中的第一步会导致
x
变为0。如果这两个值仅仅相等,但仍然是独立的内存块,这是可以的,因为第二步将保持
y
不变(因为
x
为0),如果
y
现在等于原始值,第三步将恢复
x
的原始值


然而,当
x
y
实际上是内存中的同一对象时,每个算法中的第一个操作在将
x
设置为0时,也将
y
设置为0,因为
y
x
。因此,每个算法的其余部分仅在该内存空间中保留值0

为什么要将数组项与其自身交换?为什么要为此使用宏?为什么要编写混乱的代码?宏很难调试。最好避免。不管怎样,C++有“代码> STD::SWIFT/CONTH> @ VioletGiraffe,大概是为了测试交换实现,或者是在不知道它们是相同的上下文中。”EdHealthEw,显然不是,或者OP大概会得到正确的结果。是的,任何与自身异或的值都是0,但这不是算法结束的地方。第二种算法也是如此。在算法上,使用宏和使用函数之间没有区别。是的,我错了,对不起。它仍然引用相同的变量并导致相同的结果;掉期(a、b)并观察。如果你要编写一个函数,为什么不在没有XOR繁琐的情况下正确地编写它?@EdHeal它是函数还是宏不是OP的问题。
std::swap
是否优于异或交换也不是OP的问题。我只是想解释为什么他没有得到他所期望的,以及如何解决它。