我有一系列花车,我想做一些交换。所以,我环顾四周,发现最有效的方法是通过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 *’)
。
老实说,我不是指针的专家,有时会让我感到困惑,所以,有人可以告诉我我做错了什么。
答案 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]);
如果x
是int
的数组,它会交换数组元素的内容,正如我所想的那样。当您直接使用XOR交换时,而不是通过函数,您根本不需要使用指针。例如:
if(x[i]!=x[j]) {
x[i] ^= x[j];
x[j] ^= x[i];
x[i] ^= x[j];
}
如果x
是int
而不是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所示,它应该不起作用。只有整数。