奇怪的交换宏

Strange swap macro

本文关键字:交换      更新时间:2023-10-16

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

#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    
}

有人能帮我吗?

你的问题是你的交换算法要求两个参数是分开的内存块。

LYF_HKN指出,每个算法的第一步使xx=y时变为0。如果这两个只是等于,但仍然是独立的内存块,这很好,因为第二步将使y保持不变(因为x为0),并且如果 y现在等于原始值,第三步将恢复x 的原始值。

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

第一个SWAP:

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

任何与自身异或的值都是零。这就是为什么第一次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的值是多少,都是0

第一个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;
    }
}