【问题标题】:Why incrementing int primitive in while loop does not loop forever为什么在while循环中增加int原语不会永远循环
【发布时间】:2014-01-31 20:36:20
【问题描述】:

我有以下代码示例

int i = 1;  

while(i != 0) {  
    i++;  
} 

我原以为它会在无限循环中运行,但事实并非如此。然后当我在while循环之后打印值时,我得到:

i value is 0.  

谁能告诉我到底发生了什么?

【问题讨论】:

  • 更重要的是,您为什么认为它应该导致内存问题?这里的内存在哪里用完?
  • Can any one let me know what exactly is happening? -- 整数溢出。
  • “我原以为它会在无限循环中运行,但它没有。”如果你想要一个无限循环,你可以做“while (true) {}”

标签: java increment post-increment


【解决方案1】:

intint:对于每个 i,如果 iint,那么 i+1 也是。 int 始终是 32 位的,它永远不需要更大的容器。

最后,你的循环不是无限的。

【讨论】:

    【解决方案2】:

    我原以为它会在无限循环中运行,但它没有。

    不,不会。 最终这个值会再次变成0。

    具体来说,它会像这样在逻辑上执行:

    1
    2
    3
    ...
    2,147,483,646
    2,147,483,647  
    -2,147,483,648  // Integer overflow => wrapping
    -2,147,483,647
    ...
    -3
    -2
    -1
    0
    

    ...然后循环将结束

    来自section 15.18.2 of the JLS

    如果整数加法溢出,则结果是数学和的低位,以某种足够大的二进制补码格式表示。如果发生溢出,则结果的符号与两个操作数值的数学和的符号不同。

    这段代码没有内存问题,因为它不执行任何分配 - 它只是增加一个局部变量,完全在堆栈上。

    现在是否实际上这样做是另一回事 - 如果 JIT 能够在不执行每次迭代的情况下计算出行为将是什么,它可以优化它 - 但这是一个实施细节。重要的部分是理解行为背后的逻辑。

    【讨论】:

    • 非常感谢。是的,我期待堆内存异常而不是堆栈溢出错误,这太愚蠢了。但是现在我知道为什么它没有在无限循环中运行以及为什么没有错误。
    • @SrikanthGanji:你为什么会期望堆栈溢出?循环内也不再分配堆栈内存 - 它只是用另一个值替换一个值。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-05-30
    • 2018-08-14
    • 1970-01-01
    • 2011-01-20
    • 2021-11-28
    • 1970-01-01
    • 2018-10-12
    相关资源
    最近更新 更多