应用XOR交换算法时指针问题

时间:2017-07-11 14:26:38

标签: c arrays algorithm

我有一系列花车,我想做一些交换。所以,我环顾四周,发现最有效的方法是通过XOR交换XOR swap algorithm

所以我有这段代码:

  float tmp;
  tmp   = x[i];
  x[i]  = x[j];
  x[j]  = tmp;

我尝试将其更改为XOR交换方式:

  /*Made sure that address x[i] is different than the one of x[j] */
  float* a= &x[i];
  float* b= &x[j];
  a ^= b;
  b ^= a;
  a ^= b;

但我明白了:error: invalid operands to binary ^ (have ‘float *’ and ‘float *’)

老实说,我不是指针的专家,有时会让我感到困惑,所以,有人可以告诉我我做错了什么。

3 个答案:

答案 0 :(得分:2)

修改

简短回答:您无法对指针执行按位操作。不幸的是,你cannot perform bitwise operations on floats, either!不要将XOR交换用于float值。

原始

评论者给了你简短的答案。现在我采取长期答案 -

为整数定义了^等按位运算。但是,指针不一定是整数。在实模式x86上,指针包含或以某种方式与两个整数相关:一个段和一个偏移量(additional info)。  更糟糕的是,这两个整数重叠,因此对一个整数的改变也会改变另一个整数。因此,没有单一,明确的方法来为指针定义^或其他按位操作。

许多代码确实假设指针可以被视为整数,因为分段寻址不像以前那么常见。但是,C标准仍然必须支持不太常见的体系结构,因此不会在指针上定义按位操作。

其余编辑

我看到您链接的示例使用指针。这是因为,在C中,您必须使用指针通过参数将值传递回函数的调用者。 code you linked是:

void xorSwap (int *x, int *y) {
     if (x != y) {
         *x ^= *y;
         *y ^= *x;
         *x ^= *y;
     }
 }

(enwiki,CC-BY-SA 3.0)。您可以在上下文中将其称为

if(x[i]!=x[j]) xorSwap(&x[i], &x[j]);

如果xint的数组,它会交换数组元素的内容,正如我所想的那样。当您直接使用XOR交换时,而不是通过函数,您根本不需要使用指针。例如:

if(x[i]!=x[j]) {
    x[i] ^= x[j];
    x[j] ^= x[i];
    x[i] ^= x[j];
}
如果xint而不是float

应该再次有用。

答案 1 :(得分:2)

如果使用指针执行a ^= b,则需要交换地址而不是实际值。相反,你应该使用这些值。下一个问题是你想要XOR浮点数而这是不可能的。相反,您可以获取浮动的单个字节并对它们进行异或运算:

void swap( float * one, float * two){
    unsigned char* a= (unsigned char *)one;
    unsigned char* b= (unsigned char *)two;

    for(int i = 0; i < sizeof(float); i++){
        *a ^= *b;
        *b ^= *a;
        *a ^= *b;
        a++;
        b++;
    }
}

int main(void) {
    float one = 1.0, two = 2.0;

    swap(&one, &two);
    printf("%f    %f", one, two); // prints 2.0000    1.0000
    return 0;
}

这是一项额外的工作,不值得付出努力而且确实更慢。您可以使用XOR交换进行整数和常规交换,并使用临时变量进行浮动。

答案 2 :(得分:-1)

这很正常。

  float* a= x[i];

无效。你的浮点数是x。 您正在尝试从数组中获取值。 所以它应该是:

float a = x[i];
float b = x[j];

如果你输入'*',你会做一个指针。 无论如何,正如Wikipedia所示,它应该不起作用。只有整数。