如何使用 XOR 赋值运算符 ^= 来反转 c 中的数组
Posted
技术标签:
【中文标题】如何使用 XOR 赋值运算符 ^= 来反转 c 中的数组【英文标题】:How XOR Assignment operator ^= is utilized to reverse an array in c 【发布时间】:2021-10-29 13:32:51 【问题描述】:我遇到过这个函数
void reverseArray(int *a,int n)
for(int i=0,j=n-1;i<j;i++,j--)
a[i]^=a[j]^=a[i]^=a[j];
它正在反转给定的数组,但我无法理解这如何反转数组,Xor 运算符不是只返回非公共位。 那么反转给定数组的逻辑是什么。
【问题讨论】:
Re“非公共位”:当你翻转a[j]
中的非公共位时,它使这些位具有它们在a[i]
中的值,因此结果等于@987654327 @。然后,从右到左,a[i]^=a[j]
找到非公共位 (^
) 并将它们 (^=
) 存储在 a[i]
中。然后a[j]^=a[i]^a[j]
翻转a[j]
中的那些位,使其等于原始a[i]
。然后a[i]^=a[j]^=a[i]^=a[j]
将存储在a[i]
中的非公共位与a[i]
(现在在a[j]
中)的原始值进行异或,这样翻转非公共位以生成原始a[j]
,这存储在a[i]
。
需要注意的是,这条语句的行为并没有被C标准定义,因为a[i]
的更新是没有顺序的。
请注意,有两种截然相反的方法可以回答这个问题。 (1) 这段代码的作者试图实现一个(反常的)目标,我们可以解释这个目标是什么,以及它是如何实现的。但是(2)正如您自己亲眼所见,此代码在第一次阅读时是不可能理解的。此外,它是未定义的:它甚至不能保证工作。因此,虽然这可能是一个值得学习的有用示例,但绝对绝对不是值得钦佩、模仿或用于真实、实用的程序的东西!
在C FAQ list 中查看Question 20.15c。
见What is the difference between two different swapping function?
【参考方案1】:
a ^= b ^= a ^= b;
是一种交换两个数字的奇特方式,称为XOR swap。
您应该更喜欢可读性更高的std::swap
,或(在 C 中)临时变量。
【讨论】:
s/fancy/obfuscated/. C++ 有std::reverse
。你甚至不需要在 for 循环中使用 std::swap
。【参考方案2】:
表达式a^=b^=a^=b
的目的是交换a
和b
的值。如果我们将其拆分(其中a_0
和b_0
是a
和b
的原始值)会变得更加清晰:
-
第一次分配,
a^=b
使a_1=(a_0^b_0)
。
第二次分配,b^=a
使b_1=(b_0^a_1)=(b_0^(a_0^b_0))=a_0
第三次分配,a^=b
使a_2=(a_1^b_1)=((a_0^b_0)^a_0)=b_0
因此,我们最终得到 a
的原始值为 b
,反之亦然。
虽然表达式a^=b^=a^=b
可能有效,但它实际上是未定义的行为,因为C 标准没有指定赋值的顺序。相反,它必须明确排序:a^=b; b^=a; a^=b;
。
【讨论】:
以上是关于如何使用 XOR 赋值运算符 ^= 来反转 c 中的数组的主要内容,如果未能解决你的问题,请参考以下文章