为什么通过XOR交换整数变量不能在单行中工作? [英] Why swapping integer variable by XOR doesn't work in a single line?

查看:84
本文介绍了为什么通过XOR交换整数变量不能在单行中工作?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想使用XOR运算符在java中交换两个整数变量的值。

I want to swap the value of two integer variables in java using the XOR operator.

这是我的代码:

int i = 24;
int j = 17;

i ^= j;
j ^= i;
i ^= j;

System.out.println("i : " + i + "\t j : " + j);

它会正常工作,但以下等效代码不起作用:

It will work fine but the following equivalent code doesn't work:

int i = 24;
int j = 17;

i ^= j ^= i ^= j;

System.out.println("i : " + i + "\t j : " + j);

输出如下:

i : 0    j : 24

第一个变量为零! Java出了什么问题?

First variable is zero! What's wrong with Java?

推荐答案

根据 Java规范(Java 7规范),第15.26.2节(第529页)。

According to Java specification (Java 7 specification), Section 15.26.2 (page 529).


形式 E1 op = E2 的复合赋值表达式相当于 E1 =(T)((E1)op(E2)),其中 T E1 ,但 E1 仅评估一次。

A compound assignment expression of the form E1 op= E2 is equivalent to E1 = (T) ((E1) op (E2)), where T is the type of E1, except that E1 is evaluated only once.

根据到第15.7节评估订单(页423)( 重点 我的):

According to Section 15.7 Evaluation Order (Page 423) (emphasis mine):


15.7评估顺序



Java编程语言保证运算符的操作数似乎以特定的评估顺序进行评估,即从左到右右边。

15.7 Evaluation Order

The Java programming language guarantees that the operands of operators appear to be evaluated in a specific evaluation order, namely, from left to right.

Th在评估右手操作数的任何部分之前,二元运算符的左侧操作数似乎已完全评估。

The left-hand operand of a binary operator appears to be fully evaluated before any part of the right-hand operand is evaluated.

如果运算符是一个复合赋值运算符(第15.26.2节),然后对左侧操作数的计算包括记住左侧操作数表示的变量和获取并保存该变量的值以用于隐含的二进制操作。

If the operator is a compound-assignment operator (§15.26.2), then evaluation of the left-hand operand includes both remembering the variable that the left-hand operand denotes and fetching and saving that variable's value for use in the implied binary operation.

如果对二元运算符的左侧操作数的求值突然完成,则右侧操作数的任何部分似乎都没有被评估过。

If evaluation of the left-hand operand of a binary operator completes abruptly, no part of the right-hand operand appears to have been evaluated.

第15.26.2节(第529页)中详细介绍:

Described in more details in Section 15.26.2 (page 529):


如果左侧操作数表达式不是数组访问表达式,则:

If the left-hand operand expression is not an array access expression, then:

•首先,评估左侧操作数以生成变量。 [trimmed]

• First, the left-hand operand is evaluated to produce a variable. [trimmed]

•否则,保存左侧操作数的值,然后评估右侧操作数。 [trimmed]

• Otherwise, the value of the left-hand operand is saved and then the right-hand operand is evaluated. [trimmed]

•否则,左侧变量的保存值和右侧操作数的值用于执行复合指示的二进制运算赋值运算符。 [trimmed]

• Otherwise, the saved value of the left-hand variable and the value of the right-hand operand are used to perform the binary operation indicated by the compound assignment operator. [trimmed]

•否则,二进制运算的结果将转换为左侧变量的类型,进行值集转换(§5.1.13)到适当的标准值集(不是扩展指数值集),转换结果存储在变量中。

• Otherwise, the result of the binary operation is converted to the type of the left- hand variable, subjected to value set conversion (§5.1.13) to the appropriate standard value set (not an extended-exponent value set), and the result of the conversion is stored into the variable.

文档中的示例


示例15.26.2-2。在评估右侧之前保存复合赋值的左侧值

  class Test {
      public static void main(String[] args) {
          int k = 1;
          int[] a = { 1 };
          k += (k = 4) * (k + 2);
          a[0] += (a[0] = 4) * (a[0] + 2);
          System.out.println("k==" + k + " and a[0]==" + a[0]);
      }
  }


所以表达式在问题中重写并分组为:

So the expression in the question is re-written and grouped as:

i = i ^ (j = j ^ (i = i ^ j));

评估左手操作数:

i = 24 ^ (j = 17 ^ (i = 24 ^ 17));
    **

由于 i的值未按预期更新,当 24 为时,它将导致 i 的值为0换成 j

Since the value of i is not "updated" as expected, it will cause the value of i to get 0 when 24 is swapped to j.

这篇关于为什么通过XOR交换整数变量不能在单行中工作?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆