我有一个关于使用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中有可能吗?提前谢谢!!
答案 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的字符串,这将有效