问题
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