Swap two pointers using XOR

别来无恙 提交于 2019-12-25 07:26:30

问题


I have a quick question about using XOR two swap two string literals.

so I have the following:

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

As you can see, I used binary operation XOR to for the intSwap. However, when I tried to do the same thing with swapString, it's not working.

I get error message saying: invalid operands to binary ^ (have ‘char *’ and ‘char *’)

Do you know how to use XOR to swap two string literals? Is it possible in C? Thanks ahead!!


回答1:


There are no bitwise operations on pointers. The only "arithmetic" operations that can act on them are + and - (and their childer ++, --, += and -=). So you need to cast to intptr_t (or preferably uintptr_t when doing bitwise operations) and back.

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

Anyway, it's a bad practice and won't save you any cycles. The compilers will recognize swaps using simple assignments and optimize it for you. Good compilers even recognize those XOR pessimizations and convert them back to the more efficient MOVs. Here are some examples. As you can see, the above function will be compiled to the following instructions

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



回答2:


If you're using C99 or greater, you need to cast the char * to intptr_t before operating, then cast back into a char * after operating.

Your error message:

invalid operands to binary ^ (have ‘char *’ and ‘char *’)

Tells you that you while you got the concept right, the operator ^ doesn't work on pointers.

Note that if your goal is to do this without using an extra variable (note this is not actually more efficient on modern compilers), you can do this using addition and subtraction, which pointers do support well enough. See this site for details.

intptr_t is an integer type that's intended to hold pointer values. Note intptr_t is not strictly speaking fully portable (there may not be an integer type that can hold pointers) per this SO answer.




回答3:


*a=*b; means one char of b will be copied to a, not the whole string. The same applies to swapString function so this will produce the wrong value.

If you try the same with a string with length 1 this will work



来源:https://stackoverflow.com/questions/23178016/swap-two-pointers-using-xor

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!