谜题30:循环者的爱子

请提供一个对i的声明,将下面的循环转变为一个无限循环:


while (i != i + 0) {

}

与前一个谜题不同,你必须在你的答案中不使用浮点数。换句话说,你不能把i声明为double或float类型的。

与前一个谜题一样,这个谜题初看起来是不可能实现的。毕竟,一个数字总是等于它自身加上0,你被禁止使用浮点数,因此不能使用NaN,而在整数类型中没有NaN的等价物。那么,你能给出什么呢?

我们必然可以得出这样的结论,即i的类型必须是非数值类型的,并且这其中存在着解谜方案。唯一的 + 操作符有定义的非数值类型就是String。+ 操作符被重载了:对于String类型,它执行的不是加法而是字符串连接。如果在连接中的某个操作数具有非String的类型,那么这个操作书就会在连接之前转换成字符串[JLS 15.18.1]。

事实上,i可以被初始化为任何值,只要它是String类型的即可,例如:


String i = "Buy seventeen copies of Effective Java";

int类型的数值0被转换成String类型的数值”0”,并且被追加到了感叹号之后,所产生的字符串在用equals方法计算时就不等于最初的字符串了,这样它们在使用==操作符进行计算时,当然就不是相等的。因此,计算布尔表达式(i != i + 0)得到的值就是true,循环也就永远不会被终止了。

总之,操作符重载是很容易令人误解的。在本谜题中的加号看起来是表示一个加法,但是通过为变量i选择合适的类型,即String,我们让它执行了字符串连接操作。甚至是因为变量被命名为i,都使得本谜题更加容易令人误解,因为i通常被当作整型变量名而被保留的。对于程序的可读性来说,好的变量名、方法名和类名至少与好的注释同等重要。

对语言设计者的教训与谜题11和13中的教训相同。操作符重载是很容易引起混乱的,也许 + 操作符就不应该被重载用来进行字符串连接操作。有充分的理由证明提供一个字符串连接操作符是多么必要,但是它不应该是 + 。

原文地址:https://www.cnblogs.com/yuyu666/p/9840455.html

时间: 2024-10-30 07:47:34

谜题30:循环者的爱子的相关文章

C#解惑30: 循环者的爱子

谜题30: 循环者的爱子 请提供一个对i的声明,将下面的循环转变为一个无限循环: while (i != i + 0) { } 与前一个谜题不同,你必须在答案中不使用浮点数.换句话说,你不能把i声明为double或float类型. 解惑30: 循环者的爱子 与前一个谜题一样,这个谜题初看起来是不可能实现的.毕竟,一个数字总是等于它自身加上0,你被禁止使用浮点数,因此不能使用NaN.而在整数类型中没有NaN的等价物.那么,你能给出什么呢? 我们必然可以得出这样的结论,即i的类型必须是非数值类型的,

Java解惑三:循环之谜

谜题24 byte是有符号的,范围是-128 - 127.而0x90是int类型.比较的时候,不相等. 如果想让其相等,需要进行类型转换:(byte & 0xff) 或者 (byte)0x99. 谜题25 自增运算符对循环的影响.j = j++,先赋值. 谜题26 Integer.MAX_VALUE加一之后会变成Integer.MIN_VALUE,这对循环会有影响. 可以考虑使用long来表示i变量,或者使用效率更高的i != Integer.MAX_VALUE. 谜题27 (-1 <<

循环-01. 求整数段和(15)

给定两个整数A和B,输出从A到B的所有整数以及这些数的和. 输入格式: 输入在一行中给出2个整数A和B,其中-100<=A<=B<=100,其间以空格分隔. 输出格式: 首先顺序输出从A到B的所有整数,每5个数字占一行,每个数字占5个字符宽度,向右对齐.最后在一行中输出全部数字的和. 输入样例: import java.util.Scanner; public class Main { public static void main(String[] args) { Scanner ci

JS 循环 while for do while

1 <!DOCTYPE html> 2 <html> 3 <head> 4 <meta charset="UTF-8"> 5 <title></title> 6 </head> 7 <body> 8 </body> 9 <script type="text/javascript"> 10 // 程序共有三种结构 顺序结构 .分支结构.循环结构 11

C#解惑29: 循环者的新娘

谜题29: 循环者的新娘 请提供一个对i的声明,将下面的循环转变为无限循环: while (i != i) { } 解惑29: 循环者的新娘 这个循环可能比前一个更令人困惑.不管在它前面作何种声明,它看起来确实应该立即终止.一个数字总是等于它自己,对吧? 对,但IEEE 754浮点算术保留了一个特殊的值用来表示一个不是数字的数量.这个值就是NaN("Not a Number(不是一个数字)"的缩写),对于所有没有良好的数字定义的浮点计算,例如0.0/0.0,其值都是它.规范中描述道,N

JavaScript里的循环方法:forEach,for-in,for-of

JavaScript诞生已经有20多年了,我们一直使用的用来循环一个数组的方法是这样的: for (var index = 0; index < myArray.length; index++) {  console.log(myArray[index]); } 自从JavaScript5起,我们开始可以使用内置的forEach方法: myArray.forEach(function (value) {  console.log(value); }); 写法简单了许多,但也有短处:你不能中断循环

JavaScript里的循环方法之forEach,for-in,for-of

JavaScript一种直译式脚本语言,是一种动态类型.弱类型.基于原型的语言,内置支持类型.它的解释器被称为JavaScript引擎,为浏览器的一部分,广泛用于客户端的脚本语言,最早是在HTML(标准通用标记语言下的一个应用)网页上使用,用来给HTML网页增加动态功能. JavaScript诞生已经有20多年了,我们一直使用的用来循环一个数组的方法是这样的: for (var index = 0; index < myArray.length; index++) { console.log(m

flex for循环

一:for var i:int; for (i = 0; i < 5; i++) { trace(i); } 二:for ...in 循环object: var myObj:Object = {x:20, y:30}; for (var i:String in myObj) { trace(i + ": " + myObj[i]); } // output: // x: 20 // y: 30 循环array: var myArray:Array = ["one&quo

全面解析js中的for循环

JavaScript诞生已经有20多年了,我们一直使用的用来循环一个数组的方法是这样的: for(var index=0;index<myArray.length;index++) { console.log(myArray[index]); } 自从JavaScript5起,我们开始可以使用内置的forEach方法: myArray.forEach(function (value) { console.log(value); }); 写法虽然简单了很多,但是有很多的短处:不能中断循环(使用br