使用XOR交换两个指针

问题描述 投票:0回答:3

我有一个关于使用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中有可能吗?谢谢!

c swap xor
3个回答
7
投票

指针上没有按位操作。可以作用于他们的唯一“算术”操作是+-(以及他们的childer ++--+=-=)。所以你需要转换为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;
}

无论如何,这是一个不好的做法,不会为你节省任何周期。编译器将使用简单的分配识别交换并为您优化。好的编译器甚至可以识别那些XOR悲观并将它们转换回更高效的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

4
投票

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

您的错误消息:

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

告诉你,当你有了正确的概念时,运算符^不适用于指针。

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

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


1
投票

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

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

© www.soinside.com 2019 - 2024. All rights reserved.