【问题标题】:Why doesn't the post increment operator work on a method that returns an int?为什么后自增运算符不适用于返回 int 的方法?
【发布时间】:2013-02-23 20:54:59
【问题描述】:
public void increment(){
    int zero = 0;

    int oneA = zero++; // Compiles

    int oneB = 0++; // Doesn't compile

    int oneC = getInt()++; // Doesn't compile
}

private int getInt(){
    return 0;
}

都是int的,为什么B&C编译不出来?是否与++ 运算符与= 0 + 1; 不同的方式有关?

操作参数无效 ++/--

【问题讨论】:

  • 附注:从您命名变量的方式来看,您似乎认为int oneA = zero++;one 分配给oneA。这是不正确的。 post 递增运算符返回 old(非递增)值。在int oneA = zero++; 之后,oneA0zero1
  • 所以在你的代码中你不会只是自动写int oneC = getInt() + 1; ?
  • 代码中有两个错误——一个可能是疏忽;另一个是作为问题基础的误解。基于误解的 NARQ。
  • @Kris ++ 令人困惑。 ++ 有很多问题,一旦解决方案看起来很简单。
  • @Kris :一个问题的答案对你来说是显而易见的这一事实不足以让这个问题变得毫无价值。 ++ 真的让很多人感到困惑,而且大多数人都犯了错误并从中吸取了教训。

标签: java post-increment


【解决方案1】:

i++ 是对变量i 的赋值。

在您的情况下,zero++ 等效于 zero = zero + 1。所以0++ 意味着0 = 0 + 1,这没有意义,还有getInt() = getInt() + 1

更准确地说:

int oneA = zero++;

意思

int oneA = zero;
zero = zero + 1; // OK, oneA == 0, zero == 1

int oneB = 0++;

意思

int oneB = 0;
0 = 0 + 1; // wrong, can't assign value to a value.

int oneC = getInt()++;

意思

int oneC = getInt();
getInt() = getInt() + 1; // wrong, can't assign value to a method return value.

从更一般的角度来看,变量是一个L-value,意味着它指的是一个内存位置,因此可以被赋值。 L-value 中的 L 代表赋值运算符的 left 侧(即=),即使可以找到 L-values在赋值运算符的左侧或右侧(例如x = y)。

相反的是R-valueR代表赋值运算符的right侧)。 R-values 只能用在赋值语句的右侧,将某些东西赋给 L-value。通常,R 值是文字(数字、字符串...)和方法。

【讨论】:

  • 啊当然是啊,因为它在做作业,所以 B & C 没有意义是的!
  • +1 ,我只是想对这个答案添加一点评论,'i'是一个内存分配持有一个值并有一个地址,所以 i++ 表示 1-转到内存上的地址2-获取此地址中的值 3-递增它 4-重新分配此地址中的值 'i=i+1' ,因此当我们不初始化变量时,例如 :int x ,然后 x++;我们得到错误是因为这个地址中没有值,如果是 0++,是的,它没有意义,因为 0 只是一个值
  • 其实i = i + 1 似乎等价于++i,而不是i++。 (在 Java 中看到赋值会产生值,其实我有点震惊)
  • @TV'sFrank 你是对的,i=i+1 相当于 ++i。赋值具有价值,就像在 C 和许多其他语言中一样。因此你可以写像 i=j=0;
  • 你是对的。但在这种情况下,结果是相同的:0 = 0 ; 0 + 1;getInt() = getInt(); getInt() + 1; 没有更多意义 :)
【解决方案2】:

因为如JLS中所述:

后缀表达式的结果必须是一个类型的变量 可转换(第 5.1.8 节)为数字类型,或编译时错误 发生。

【讨论】:

    【解决方案3】:

    getInt() 不是int

    getInt() 返回int

    ++ 操作员做了两件事increment + assignment

    所以要让++ 运算符工作,您需要一个变量来存储增量操作的结果,而0getInt() 都没有。

    【讨论】:

      【解决方案4】:

      前置和后置运算符仅在调用时对变量或左值进行操作。 lvalue 是左值的缩写,即在赋值中可以站在左边的东西。 在您的示例中:

          zero = 1; // OK
          0 = 1; // Meaningless
          getInt() = 1; // Also meaningless
      

      //jk

      【讨论】:

        【解决方案5】:

        B 和 C 都让编译器说:

        意外类型,必需:变量,找到:值

        所以你不能增加一个值,只能增加一个变量。

        【讨论】:

          【解决方案6】:

          为什么后自增运算符不适用于返回 int 的方法?

          因为它是一个getter方法,通过getter改变一个值是没有意义的。


          int z = x + y++;
          

          相当于:

          int z = x + y;
          y = y + 1;
          

          所以有类似的东西是无效的:

          int z = x + getY()++;
          

          相当于:

          int z = x + getY();
          getY() = getY() + 1; // invalid!
          

          【讨论】:

          • 所以如果该方法被称为 setInt ,它会增加它吗??
          • @HussainAkhtarWahid 当然不是,我的意思是当你想修改一些变量时,你可以通过 setter 而不是 getter 来做到这一点。更新了我的答案。
          • ++ 这个getY() = getY() + 1; // invalid!
          【解决方案7】:

          0++

          相当于0 = 0 + 1;,当然不可能。

          即它必须是 l-value 才能分配给它。

          getInt()++;

          这里有类似的原因。

          【讨论】:

          • + 很好的答案 ++(i|i) 呢?因为i | i 总是i 还有i & i==i
          【解决方案8】:

          因为0rValue(即您只能从赋值运算符的右侧使用它)not a lValue

          ++ 运算符递增值并将其设置为自身,因此0++ 会给您一个错误。

          【讨论】:

            【解决方案9】:

            我的回答是“开箱即用”。

            当我对某个运算符的用法有疑问时,我认为该运算符的“它与哪个重载函数等价”?

            我知道,Java 运算符没有运算符重载,它只是另一种解决方案。

            在这种情况下:

            ...
            x++;
            ...
            

            应该读作:

            ...
            
            int /* function */ postincrement (/* ref */ int avalue)
            {
              int Result = avalue;
            
              // reference value, 
              avalue = avalue + 1;
            
              return Result;
            }
            
            ...
            postincrement(/* ref */ x);
            ...
            

            还有:

            ...
            ++x;
            ...
            
            ...
            
            int /* function */ preincrement (/* ref */ int avalue)
            {
              // reference value, 
              avalue = avalue + 1;
            
              int Result = avalue;
            
              return Result;
            }
            
            ...
            preincrement(/* ref */ x);
            ...
            

            因此,两个版本的“++”都作为一个通过引用接收可变参数的函数。

            因此,像“0++”这样的字面值或像“getInt()++”这样的函数结果,都不是变量引用。

            干杯。

            【讨论】:

              【解决方案10】:

              postincrement 和 preincrement 只能在变量的帮助下应用。所以第一种情况编译。

              【讨论】:

                【解决方案11】:

                由于函数返回是 RHS 表达式,并且前/后递增/递减操作只能应用于 LHS 表达式。

                【讨论】:

                  猜你喜欢
                  • 1970-01-01
                  • 2016-02-28
                  • 2015-01-02
                  • 2021-09-26
                  • 1970-01-01
                  • 1970-01-01
                  • 2013-09-22
                  • 1970-01-01
                  相关资源
                  最近更新 更多