“在不使用第三个变量的情况下交换两个变量的值”中的潜在问题
我最近提出了这种方法,可以在不使用第三个变量的情况下交换两个变量的值。
a^=b^=a^=b
但是当我在不同的编译器上尝试上面的代码时,我得到了不同的结果,有些给出了正确的结果,有些则没有。
代码有什么严重错误吗?
I recently came along this method for swapping the values of two variables without using a third variable.
a^=b^=a^=b
But when I tried the above code on different compilers, I got different results, some gave correct results, some didn't.
Is anything terribly wrong with the code?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(8)
是的!
a^=b^=a^=b
实际上会调用 C 和 C++ 中的未定义行为,因为您试图在两个序列之间多次更改a
的值点。尝试用书写(尽管不是万无一失)
代替
a^=b^=a^=b
。PS:切勿尝试在不使用第三个变量的情况下交换两个变量的值。始终使用第三个变量。
编辑:
@caf注意到
b^=a^=b^=
运算符的参数求值顺序,> 也可以,因为表达式中对b
的所有访问都用于计算最终值被存储在b
中,行为已明确定义。Yes!
a^=b^=a^=b
in fact invokes Undefined Behaviour in C and in C++ because you are trying to change the value ofa
more than once between two sequence points.Try writing (although not foolproof )
instead of
a^=b^=a^=b
.P.S : Never try to swap the values of two variables without using a third one. Always use a third variable.
EDIT :
As @caf noticed
b^=a^=b
is fine even though the order of evaluation of arguments of^=
operator is unspecified, since all the accesses ofb
within the expression are being used to compute the final value that is being stored inb
, the behaviour is well defined.如果您使用 C++,为什么不在 STL 中使用交换算法呢?它非常适合此目的,并且它的作用非常清楚:
If you're using C++, why not use the swap algorithm in STL? It is ideal for this purpose and it's very clear what it does:
基于 R. & 的贡献sellibitze:
使用逗号运算符:
From text &维基百科:
“逗号运算符可用于将相关表达式链接在一起。逗号链接的表达式列表从左到右计算,最右边表达式的值是组合后的值它充当序列点。”
“序列点保证先前计算的所有副作用都已执行,并且后续计算的副作用尚未执行。它会删除未定义的内容。由于原始表达式的执行顺序不明确而产生的行为。”
Based on contributions from R. & sellibitze:
Use the comma operator:
From text & Wikipedia:
"The comma operator can be used to link the related expressions together. A comma-linked list of expressions is evaluated left-to-right and the value of the rightmost expression is the value of the combined expression. It acts as a sequence point."
"A sequence point guarantees that all side effects of previous evaluations will have been performed, and no side effects from subsequent evaluations have yet been performed. It removes the undefined behavior arising out of the unclear order of execution of the original expression."
我建议您对 c++ 使用 std::swap() 。
对于 c,请使用此宏。请注意,您需要先比较 a 和 b,否则当它们指向同一内存位置时,您将擦除该值并使其变为 0。
I suggest that you use std::swap() for c++.
For c, use this macro. Notice that you need to compare a and b first, otherwise when they are point to the same memory location you will wipe out the value and it becomes 0.
这样做:
Do it like this:
这个呢?
What about this one?
我想知道为什么没有人建议在表达式中加上括号。看来已经不是UB了
I wondered why nobody suggested parenthesizing the expression. Seems it's not UB anymore.
您也可以尝试以下一种,但如果数字足够大,值就会溢出
You can try the following one also, but if to numbers are large enough value will overflow