为什么赋值语句左侧不能是递增表达式?

5

请问在Java中,下面这段代码中的"++"与数组有什么意义:

   int [ ] arr = new int[ 4 ];
   for(int i = 0; i < arr.length; i++){
        arr[ i ] = i + 1;
       System.out.println(arr[ i ]++);
   }

在上述代码中,“arr[i]++”是什么意思,为什么我们不能这样做:
arr[ i ]++ = i + 1;

1
在Java代码中从未见过这样的编程风格(方括号内带有空格)。 - Roman
顺便提一下,++ 运算符的字节码取决于它是否用于本地 int 变量以及结果是否被使用。最简单的情况是对本地 int 变量进行单个增量指令的裸增量。而你的情况是对数组成员进行后增量,这将生成一些最复杂的字节码。(我无法评论任何 JIT 转换。) - Neil
6个回答

7
讨论的运算符称为后缀递增运算符(JLS 15.14.2)。其行为如下所述:
  1. 在运行时,如果操作数表达式的求值突然完成,则后缀递增表达式由于同样的原因而突然完成,不会发生递增。
  2. 否则,将值1添加到变量的值中,并将总和存回变量中。
    1. 在执行加法之前,对值1和变量的值进行二进制数值提升(§5.6.2)。
    2. 如果需要,将总和通过缩小的原始转换(§5.1.3)和/或装箱转换(§5.1.7)缩小为变量的类型,然后再将其存储。
  3. 后缀递增表达式的值是存储新值之前变量的值
最后一点是这个问题的关键:为什么你不能执行 arr[i]++ = v;,原因与你不能执行 x++ = v; 完全相同;后缀递增表达式返回一个,而不是一个变量
来自 JLS 15.1 Evaluation, Denotation and Result

当程序中的表达式被评估(执行)时,结果表示以下三种情况之一:

  • 一个变量[...](在C中,这将被称为lvalue)
  • 一个值[...]
  • 没有任何东西(该表达式被称为空)
赋值需要左侧是一个变量,而一个值不是一个变量,这就是为什么你不能执行x++ = v;
来自 JLS 15.26 Assignment Operators

赋值运算符的第一个操作数的结果必须是变量,否则会出现编译时错误。这个操作数可以是命名变量[...],也可以是计算变量,例如来自字段[...]或数组访问的结果。 [...]

以下代码片段显示了对进行赋值的错误尝试,从微妙到更明显:

int v = 42;
int x = 0;
x = v;        // OKAY!
x++ = v;      // illegal!
(x + 0) = v;  // illegal!
(x * 1) = v;  // illegal!
42 = v;       // illegal!
   // Error message: "The left-hand side of an assignment must be a variable"

请注意,您可以在赋值运算符的左侧的某个位置使用后缀递增运算符,只要最终结果是一个变量。
int[] arr = new int[3];
int i = 0;
arr[i++] = 2;
arr[i++] = 3;
arr[i++] = 5;
System.out.println(Arrays.toString(arr)); // prints "[2, 3, 5]"

2

System.out.println(arr[i]++)这段代码的意思是:

int tmp = arr[i];
arr[i] = arr[i] + 1;
System.out.println(tmp);

你的第二个例子没有意义,因为你不能在一个值上使用++运算符。

2
arr[i]++表示“将arr[i]的值增加1”,并返回旧值。因此,您的代码首先使用arr[ i ] = i + 1;arr[i]设置为i+1。然后,它使用arr[ i ]++将其增加到i + 2,并打印在第二次增加之前它所具有的值,即i + 1
您不能使用arr[ i ] = arr[i] + 1;,因为它意味着“将arr[i]的值增加1并返回新值”。
您不能使用arr[ i ]++ = i + 1;,因为这没有意义。

1
代码没有先增加arr[i]的值。那应该是arr[i] = arr[i] + 1。但它写成了arr[i] = i + 1。这是不同的。 - Mark Byers

1

++ 运算符与数组无关。它将任何整数变量(或更一般地说,任何左值)增加 1。它与循环中的 i++ 相同。

您可以编写 ++x 或 x++。这两个都会增加 x 的值,但它们具有不同的值:++x 返回 x 的新值,而 x++ 返回旧值。因此,您的代码打印 1、2、3、4 而不是 2、3、4、5。


0

arr[i]++会将arr[i]的值增加1。可能会像这样:

arr[i] = i + 1;

关于 arr[ i ]++ = i + 1; 这样的代码,请不要尝试编写。即使它可以编译,对您或他人来说也会是个谜题。
PS:我更喜欢:
++arr[i];

1
但是 ++arr[i] 会打印出不同的结果,与 arr[i]++ 不同。 - user85421
是的,你说得对。我会在一行中使用++arr[i]来增加值,并在另一行中打印输出。我认为这样更易读。 - Michał Niklas

0

arr[i]++ 是将 arr[i] 的值加一并赋值。

至于 arr[ i ]++ = i + 1; 这个短语意思完全不同,说实话我不知道它是否有效的 Java 代码。如果它有效,我会先将 arr[i] 的值增加一,然后将其分配给索引 +1。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接