奇怪的交换宏

时间:2016-09-18 05:18:57

标签: 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], ia[1])   // the result is ia[0] = 0    
}

任何人都可以帮助我吗?任何帮助将不胜感激。

3 个答案:

答案 0 :(得分:4)

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

如LYF_HKN所述,每个算法的第一步导致xx=y时变为0。如果这两个只是相等但仍然是单独的内存,这很好,因为第二步将保持y不变(因为{{1}如果 x现在等于原始值,则第三步将恢复x 的原始值。

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

答案 1 :(得分:3)

第一次SWAP:

ia[0] = ia[0] ^ ia[0];
ia[0] = ia[0] ^ ia[0];
ia[0] = ia[0] ^ ia[0];

嗯,XOR&D本身的任何值都给出零。这就是为什么第一个SWAP导致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]的值如何,始终为零。

答案 2 :(得分:2)

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

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

要使XOR swap正常工作,您需要进行一些修改:

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