使用XOR交换两个指针

时间:2014-04-20 03:11:32

标签: c swap xor

我有一个关于使用XOR两个交换两个字符串文字的快速问题。

所以我有以下内容:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>


void intSwap(int *a, int *b){
    *a=*a^*b;
    *b=*a^*b;
    *a=*a^*b;
}


void swapString(char **a, char **b){
    char *temp=*a;
    *a=*b;
    *b=temp;
}

void main(){
    char *s= "ha";
    char *t= "Oh";

    printf("%s and %s \n",s,t); // prints ha Oh
    swapString(&s,&t);
    printf("%s and %s \n",s,t); // prints Oh ha


    int a=10;
    int b=5;
    printf("%d %d\n",a,b); //print 10 5
    intSwap(&a,&b);
    printf("%d %d\n",a,b); //print 5 10
}

如您所见,我使用二进制运算XOR来获取intSwap。但是,当我尝试使用swapString做同样的事情时,它不起作用。

我收到错误消息:二进制操作数无效^(有'char *'和'char *')

你知道如何使用XOR交换两个字符串文字吗?在C中有可能吗?提前谢谢!!

3 个答案:

答案 0 :(得分:7)

指针上没有按位操作。唯一的&#34;算术&#34;可以对其采取行动的行为是+-(以及他们的++--+=-=。因此,您需要在执行按位操作时转换为intptr_t(或者最好uintptr_t)并返回。

void pointerXorSwap(int **x, int **y){
    uintptr_t a = (uintptr_t)*x;
    uintptr_t b = (uintptr_t)*y;

    a = a ^ b;
    b = a ^ b;
    a = a ^ b;

    *x = (int*)a;
    *y = (int*)b;
}

无论如何,这是一种不好的做法,并且不会为你节省任何周期。编译器将使用简单的分配识别交换并为您优化。好的编译器甚至会认识到那些异或悲观,并且将它们转换回更高效的MOV Here are some examples。如您所见,上述函数将编译为以下指令

pointerXorSwap(int**, int**):
        mov     rax, QWORD PTR [rdi]
        mov     rdx, QWORD PTR [rsi]
        mov     QWORD PTR [rdi], rdx
        mov     QWORD PTR [rsi], rax
        ret

答案 1 :(得分:4)

如果您使用的是C99或更高版本,则需要在操作前将char *转换为intptr_t,然后在操作后重新投射到char *

您的错误消息:

  

二进制操作数无效^(有'char *'和'char *')

告诉你,当你理解了这个概念时,运算符^并不适用于指针。

请注意,如果您的目标是在不使用额外变量的情况下执行此操作(请注意,在现代编译器上实际上更高效),您可以使用加法和减法执行此操作,指针支持足够好。 See this site了解详情。

intptr_t是一个整数类型,用于保存指针值。注意intptr_t严格来说并不是完全可移植的(可能没有可以保存指针的整数类型)per this SO answer

答案 2 :(得分:1)

*a=*b;表示b的一个字符将被复制到a,而不是整个字符串。这同样适用于swapString函数,因此会产生错误的值。

如果你尝试使用长度为1的字符串,这将有效