我在英国大学考试中遇到了这个难题。
考虑以下循环,到目前为止,其中i未声明:
while (i == i + 1) {}
找到i
的定义,它在这个循环之前,这样time循环就会永远继续。
下一个问题,对该代码段提出了相同的问题:
while (i != i) {}
对我来说是显而易见的。当然,在另一种情况下,它是NaN,但我真的被前一种情况困住了。这与溢出有关吗?是什么导致这样的循环在Java中永远循环?
双i=双。正无穷大;
JoshuaBloch和NealGafter的《Java谜题:陷阱、陷阱和角落案例》一书详细描述了这些谜题。
double i = Double.POSITIVE_INFINITY;
while (i == i + 1) {}
或:
double i = 1.0e40;
while (i == i + 1) {}
这两种方法都会导致无限循环,因为将足够大的浮点值相加不会改变该值,因为它不会将间隙“桥接”到后续值。
关于第二个谜题的注释(供未来读者使用):
double i = Double.NaN;
while (i != i) {}
也会导致无限循环,因为NaN不等于任何浮点值,包括其本身。
1-Java谜题:陷阱、陷阱和角落案例(第4章-循环谜题)。
JLS§15.21.1
首先,由于while(i==i 1{}循环不会更改i的值,因此使该循环无限等于选择满足i==i 1的i值。
有许多这样的价值观:
让我们从“异国情调”开始:
double i = Double.POSITIVE_INFINITY;
或
double i = Double.NEGATIVE_INFINITY;
这些值满足i==i 1
的原因在
JLS 15.18.2中说明。数字类型的加法运算符(和-):
无穷大和有限值之和等于无限操作数。
这并不奇怪,因为将有限值添加到无限值中会产生无限值。
也就是说,满足i==i 1
的i
的大多数值只是大双
(或浮点
)值:
例如:
double i = Double.MAX_VALUE;
或
double i = 1000000000000000000.0;
或
float i = 1000000000000000000.0f;
双
和浮点
类型的精度有限,因此如果您取一个足够大的双
或浮点
值,将1
添加到它将导致相同的值。
问题内容: 我不明白为什么这个职位增加方程不增加。我以为在+=操作之后,该值将增加1,然后围绕i的第二次将具有1值。但是输出是一个零零的无限循环。有谁能解释为什么“ i”不增加。 问题答案: @ njzk2的答案是正确的,但指出正确的 原因 很有用。 还有其他可能性-例如,为什么Java在分配后不执行postincrement运算符?(答案:因为那不是Java语言设计者选择的) Java语言规范第
问题内容: 我今天发现了一件奇怪的事情,想知道是否有人可以阐明其中的区别? 运行完每个循环后,没有改变,但是在每个元素中添加了一个。我实际上使用该版本在循环内写入初始化的NumPy数组。 问题答案: 不同之处在于,一个修改数据结构本身(就地操作),而另一个仅 重新分配 变量。 仅出于完整性考虑: 是 不是总是 做就地操作,有(至少)三种例外情况: 如果 没有实现 的则方法的声明仅仅是一个速记。如果
问题内容: 在Java中,我通常会进行如下所示的for循环: 但是最近一位同事打了这样的字: 他说后者会更快。真的吗? 问题答案: 不,那不是真的。您可以通过定时每个循环进行大量迭代来衡量性能,但是我可以肯定它们会是相同的。 神话来自C,它被认为比C 更快,因为前者可以通过增加i然后返回来实现。后者可以通过将i的值复制到临时变量,递增i,然后返回临时变量的方式来实现。第一个版本不需要制作临时副本,
问题内容: 我试图打印/获取循环变量i的值,并在for循环之外的另一种方法中使用它。我怎么做? 问题答案: 语句中声明的变量仅在组件和以下代码块的范围内,尤其是请参阅JLS 14.14.1.1节 : 如果ForInit代码是局部变量声明,则将其执行为好像是出现在块中的局部变量声明语句(第14.4节)一样。 如果您想在之外使用它,则必须在要访问它的位置中处于活动状态的作用域中声明它;例如,就在循环之
问题内容: 哪个更正确?Java的结果为12或C =13。或者,如果不是正确性,请详细说明。 问题答案: 没有比这更正确的了。它实际上是未定义的,称为序列点错误。 http://en.wikipedia.org/wiki/Sequence_point