算法(4th ed)(62):基础——基础编程模型 3.12

阅读数:15 2019 年 10 月 30 日 07:09

算法(4th ed)(62):基础——基础编程模型 3.12

(答疑)

 什么是 Java 的字节码?

 它是程序的一种低级表示,可以运行于 Java 的虚拟机。将程序抽象为字节码可以保证 Java 程序员的代码能够运行在各种设备之上。

  Java 允许整型溢出并返回错误值的做法是错误的。难道 Java 不应该自动检查溢出吗?

 这个问题在程序员中一直是有争议的。简单的回答是它们之所以被称为原始数据类型就是因为缺乏此类检查。避免此类问题并不需要很高深的知识。我们会使用 int 类型表示较小的数(小于 10 个十进制位)而使用 long 表示 10 亿以上的数。

 Math.abs(-2147483648) 的返回值是什么?

 -2147483648。这个奇怪的结果(但的确是真的)就是整数溢出的典型例子。

 如何才能将一个 double 变量初始化为无穷大?

 可以使用 Java 的内置常数:Double.POSITIVE_INFINITYDouble.NEGATIVE_INFINITY

 能够将 double 类型的值和 int 类型的值相互比较吗?

 不通过类型转换是不行的,但请记住 Java 一般会自动进行所需的类型转换。例如,如果 x 的类型是 int 且值为3,那么表达式(x<3.1) 的值为true——Java 会在比较前将x 转换为double 类型(因为3.1是一个 double 类型的字面量)。

 如果使用一个变量前没有将它初始化,会发生什么?

 如果代码中存在任何可能导致使用未经初始化的变量的执行路径,Java 都会抛出一个编译异常。

 Java 表达式 1/01.0/0.0 的值是什么?

 第一个表达式会产生一个运行时除以零异常(它会终止程序,因为这个值是未定义的);第二个表达式的值是Infinity(无穷大)。

 能够使用 <> 比较 String 变量吗?

 不行,只有原始数据类型定义了这些运算符。请见 1.1.2.3 节。

 负数的除法和余数的结果是什么?

 表达式 a/b 的商会向 0 取整;a % b 的余数的定义是 (a/b)*b + a % b 恒等于 a。例如 -14/314/-3 的商都是 -4,但 -14 % 3-2,而 14 % -32

 为什么使用 (a && b) 而非 (a & b)

 运算符 &|^ 分别表示整数的逻辑操作异或。因此,10|6 的值为 1410^6 的值为 12。在本书中我们很少(偶尔)会用到这些运算符。&&|| 运算符仅在独立的布尔表达式中有效,原因是短路求值法则:表达式从左向右求值,一旦整个表达式的值已知则停止求值。

 嵌套 if 语句中的二义性有问题吗?

 是的。在 Java 中,以下语句:

复制代码
if <expr1> if <expr2> <stmntA> else <stmntB>

等价于:

复制代码
if <expr1> { if <expr2> <stmntA> else <stmntB> }

即使你想表达的是:

复制代码
if <expr1> { if <expr2> <stmntA> } else <stmntB>

避免这种“无主的”else 陷阱的最好办法是显式地写明所有大括号。

 一个 for 循环和它的 while 形式有什么区别?

 for 循环头部的代码和 for 循环的主体代码在同一个代码段之中。在一个典型的 for 循环中,递增变量一般在循环结束之后都是不可用的;但在和它等价的 while 循环中,递增变量在循环结束之后仍然是可用的。这个区别常常是使用 while 而非 for 循环的主要原因。

 有些 Java 程序员用 int a[] 而不是 int[] a 来声明一个数组。这两者有什么不同?

 在 Java 中,两者等价且都是合法的。前一种是 C 语言中数组的声明方式。后者是 Java 提倡的方式,因为变量的类型 int[] 能更清楚地说明这是一个整型的数组

 为什么数组的起始索引是 0 而不是 1

 这个习惯来源于机器语言,那时要计算一个数组元素的地址需要将数组的起始地址加上该元素的索引。将起始索引设为 1 要么会浪费数组的第一个元素的空间,要么会花费额外的时间来将索引减 1

 如果 a[] 是一个数组,为什么 StdOut.println(a) 打印出的是一个十六进制的整数,比如 @f62373,而不是数组中的元素呢?

 问得好。该方法打印出的是这个数组的地址,不幸的是你一般都不需要它。

 我们为什么不使用标准的 Java 库来处理输入和图形?

 我们的确用到了它们,但我们希望使用更简单的抽象模型。StdInStdDraw 背后的 Java 标准库是为实际生产设计的,这些库和它们的 API 都有些笨重。要想知道它们真正的模样,请查看 StdIn.java 和 StdDraw.java 的代码。

 我的程序能够重新读取标准输入中的值吗?

 不行,你只有一次机会,就好像你不能撤销 println() 的结果一样。

 如果我的程序在标准输入为空之后仍然尝试读取,会发生什么?

 会得到一个错误。StdIn.isEmpty() 能够帮助你检查是否还有可用的输入以避免这种错误。

 这条出错信息是什么意思?

复制代码
Exception in thread "main" java.lang.NoClassDefFoundError: StdIn

 你可能忘记把 StdIn.java 文件放到工作目录中去了。

 在 Java 中,一个静态方法能够将另一个静态方法作为参数吗?

 不行,但问得好,因为有很多语言都能够这么做。

评论

发布