在Java中,为什么我不能写i++++或(i++)++?

7
当我尝试在后缀/前缀中写入递增/递减,然后跟着另一个后缀/前缀递增/递减时,我会收到以下错误提示:Invalid argument to operation ++/--
但是,根据JLS的规定:
PostIncrementExpression:
        PostfixExpression ++

并且

PostfixExpression:
        Primary
        ExpressionName
        PostIncrementExpression
        PostDecrementExpression

所以写成:

PostfixExpression ++ ++

应该可以做到...有什么想法吗?


5
你不觉得 --++----++var++----++--++ 有点令人困惑吗? - Crozin
3
既然C++的升级版是C#,你尝试使用过i#吗?;-) - John Topley
1
@Anon - i++ 返回一个值,而不是一个引用... 这就是我的答案。 :) - John Assymptoth
2
@Crozin - 这是否令人困惑并不重要。我正在编写一个元程序,我需要了解这种东西。 - John Assymptoth
@Woot4Moo - 哎呀!这个问题有点相关啊。。 - John Assymptoth
@John 如果你在问题和标题中更加清晰明了,那么就不会引起那么多嘲笑了。但是为了你,我会将其删除。 - Woot4Moo
10个回答

23
请注意,原始语法缺乏任何语义。它只是语法,而不是每个句法有效的程序通常都是有效的。例如,变量必须在使用前声明的要求通常不包含在语法中(您可以这样做,但这很麻烦)。
后缀自增操作生成的是一个右值 - 就像您不能对文字进行后缀自增操作一样,您也不能对i++的结果进行后缀自增操作。
引用JLS (第三版,第486页):
“后缀增量表达式的结果不是变量,而是值。”

你可以将声明前使用编码到语法中吗?对于任意数量的标识符? - user395760
@delnan:Van Wijngaarden语法确实是为此而设计的。但实际上,双层语法过于复杂,你可以通过简单的属性语法来定义断言,并将其向下传播到AST中,从而达到同样的效果(如果我记得正确的话;自那节课以来已经过去了几年)。 - Joey

8
错误告诉你答案:
unexpected type
required: variable
found   : value
        (i++)++;

因此,i++会被计算为一个值,而运算符需要一个变量。

2
嗯,这取决于编译器吧。EclipseC会产生“++/--操作的参数无效”这样不太有用的错误提示。 - Joey
有趣。是的,那并不是很有帮助。上面的错误来自Sun编译器。 - JOTN

5
您只能将 ++ -- 应用于表示可修改位置(lvalue)的表达式。 ++ -- 的结果是来自该位置的值(rvalue-在增量或减量之前或之后),而不是可修改位置本身。因此,您不能说(a ++)++,就像您不能说(a + b)++一样-没有要修改的位置。

4
这个表达式 i = (i++)++; 的问题在于 (i++) 得到了一个值,而 ++ 运算符的定义是:1. 它将增加指定的变量,并将该值放置/返回给您,无论您使用后缀或前缀;2. 该运算符需要变量,无论是前缀还是后缀。但是这里正在发生的事情是 (i++) 返回一个值并将其放在 (i++) 的位置,然后你有了 (value)++ , 而 (value) 不是此运算符所期望的类型,因为它需要变量代替值。
例如,在Java中如果编译以下代码片段,将得到如下错误信息: public class A{ public void test(){ int i =0; i = (i++)++; } }
编译输出:
A.java:4: unexpected type required: variable found : value i = (i++)++; ^ 1 error

2

i++基本上是下面这个快捷方式:

(i = i+1)

而写成这样就没有任何意义:

(i = i+1)++;

对吧? :)


3
“(i = i + 1)”和“(i++)”不是相同的行为 - 前者返回i的新值,后者返回旧值。 - Anon.
抱歉,我猜我选了一个不能传达玩笑的好笑表情。我的错。为此我自罚一分。 - Kylar

1

必须记住:增量和减量(前缀和后缀)运算符始终与变量一起使用,而不是

这里我用一个示例来解释:

int i = 0;

int j = (i++)++;

以上是exe文件。

将变量i的初始值设为0(零)

(i++)中,'++'与变量i一起工作,并在执行操作后返回(1)

现在在(1)++中,'++'与(1)这个值而不是变量一起工作,这违反了Java的规则,因此会生成编译时错误Invalid argument to operation ++/--


1

这样的操作应该得到什么结果?i++ 的结果是(i 的当前值的副本),并且 i 在此之后被递增(后缀)。那么,你如何想象再次递增 i++ 的结果呢?如果 i 最初为 1,则在执行 i++++ 后它的值应该是多少,这个操作的结果应该是什么?

如果你仔细思考一下,你可能会意识到这很难定义。由于 Java 的设计者打算避免 C/C++ 中的“未定义”陷阱(而且由于这种语句的值最多是可疑的),他们可能决定明确禁止这种操作。


不,那不是原因。正如其他答案所述,原因是表达式i++的结果是一个值,而不是可以改变的引用。 - John Assymptoth
我记得那是因为评论/答案。 - John Assymptoth

0
在 i++ 中,++ 是一个后缀运算符,所以它会先返回 i 的值,然后再将其递增。那么,如果让 (i++)++ 做什么呢?它应该返回 i+1,因为 (i++ == i)?如果不是,那么 i++=i 这个语句是不是很奇怪,但是 (i++)++ != i。请考虑以下表达式:
i++  ==  i;   // true
j = i++  // j gets the value of i
j++ == i //  still true since j== i

(i++) ++ ==  j ++    //  what should be the answer here?

你考虑过 i+=2 吗?


0
为什么不使用简写的递增运算符呢?
i+=2

那里。


0
你想通过 (i++)++ 实现什么目的?
将其增加两次!!
使用循环
在循环内部进行增量操作 :)

3
当然,i += 2比循环更好。 - Stephen C

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