我有一个关于使用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中有可能吗?谢谢!
指针上没有按位操作。可以作用于他们的唯一“算术”操作是+
和-
(以及他们的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
如果您使用的是C99或更高版本,则需要在操作前将char *
投射到intptr_t
,然后在操作后再投回到char *
。
您的错误消息:
二进制操作数无效^(有'char *'和'char *')
告诉你,当你有了正确的概念时,运算符^
不适用于指针。
请注意,如果您的目标是在不使用额外变量的情况下执行此操作(请注意,这在现代编译器上实际上并不高效),您可以使用加法和减法来执行此操作,这些指针确实支持得足够好。 See this site了解详情。
intptr_t
是一个整数类型,用于保存指针值。注意intptr_t
严格来说并不是完全可移植的(可能没有可以保存指针的整数类型)per this SO answer。
*a=*b;
意味着b
的一个字符将被复制到a
,而不是整个字符串。这同样适用于swapString
函数,因此这将产生错误的值。
如果你尝试使用长度为1的字符串,这将有效