友情提示:如果本网页打开太慢或显示不完整,请尝试鼠标右键“刷新”本网页!
Java编程思想第4版[中文版](PDF格式)-第21部分
快捷操作: 按键盘上方向键 ← 或 → 可快速上下翻页 按键盘上的 Enter 键可回到本书目录页 按键盘上方向键 ↑ 可回到本页顶部! 如果本书没有阅读完,想下次继续接着阅读,可使用上方 "收藏到我的浏览器" 功能 和 "加入书签" 功能!
基数,约等于2。718 (Java 一种更精确的double 值采用 Math。E 的形式)。它在象“1。39 ×e 的…47 次方”这
样的指数表达式中使用,意味着“1。39×2。718 的…47 次方”。然而,自 FORTRAN 语言发明后,人们自然而然
地觉得 e 代表“10多少次幂”。这种做法显得颇为古怪,因为FORTRAN 最初面向的是科学与工程设计领域。
理所当然,它的设计者应对这样的混淆概念持谨慎态度(注释①)。但不管怎样,这种特别的表达方法在
C,C++以及现在的Java 中顽固地保留下来了。所以倘若您习惯将 e 作为自然对数的基数使用,那么在 Java
中看到象“1。39e…47f”这样的表达式时,请转换您的思维,从程序设计的角度思考它;它真正的含义是
“1。39×10 的…47 次方”。
①:John Kirkham 这样写道:“我最早于 1962 年在一部 IBM 1620 机器上使用 FORTRAN II。那时——包括
60 年代以及 70 年代的早期,FORTRAN 一直都是使用大写字母。之所以会出现这一情况,可能是由于早期的输
入设备大多是老式电传打字机,使用5 位Baudot 码,那种码并不具备小写能力。乘幂表达式中的‘E’也肯
定是大写的,所以不会与自然对数的基数‘e’发生冲突,后者必然是小写的。‘E’这个字母的含义其实很
简单,就是‘Exponential’的意思,即‘指数’或‘幂数’,代表计算系统的基数——一般都是 10。当
时,八进制也在程序员中广泛使用。尽管我自己未看到它的使用,但假若我在乘幂表达式中看到一个八进制
数字,就会把它认作Base 8。我记得第一次看到用小写‘e’表示指数是在70 年代末期。我当时也觉得它极
易产生混淆。所以说,这个问题完全是自己‘潜入’FORTRAN 里去的,并非一开始就有。如果你真的想使用
自然对数的基数,实际有现成的函数可供利用,但它们都是大写的。”
注意如果编译器能够正确地识别类型,就不必使用尾随字符。对于下述语句:
long n3 = 200;
它并不存在含混不清的地方,所以 200 后面的一个 L 大可省去。然而,对于下述语句:
float f4 = 1e…47f; //10 的幂数
编译器通常会将指数作为双精度数(double)处理,所以假如没有这个尾随的 f,就会收到一条出错提示,
告诉我们须用一个“造型”将 double 转换成 float。
2。 转型
大家会发现假若对主数据类型执行任何算术或按位运算,只要它们“比 int小”(即 char,byte 或者
short),那么在正式执行运算之前,那些值会自动转换成int。这样一来,最终生成的值就是int类型。所
以只要把一个值赋回较小的类型,就必须使用“造型”。此外,由于是将值赋回给较小的类型,所以可能出
现信息丢失的情况)。通常,表达式中最大的数据类型是决定了表达式最终结果大小的那个类型。若将一个
float 值与一个double值相乘,结果就是 double;如将一个 int和一个 long 值相加,则结果为 long。
3。1。14 Java 没有“sizeof ”
在C 和C++中,sizeof()运算符能满足我们的一项特殊需要:获知为数据项目分配的字符数量。在C 和C++
中,size()最常见的一种应用就是“移植”。不同的数据在不同的机器上可能有不同的大小,所以在进行一
74
…………………………………………………………Page 76……………………………………………………………
些对大小敏感的运算时,程序员必须对那些类型有多大做到心中有数。例如,一台计算机可用32 位来保存整
数,而另一台只用 16 位保存。显然,在第一台机器中,程序可保存更大的值。正如您可能已经想到的那样,
移植是令C 和C++程序员颇为头痛的一个问题。
Java 不需要 sizeof()运算符来满足这方面的需要,因为所有数据类型在所有机器的大小都是相同的。我们不
必考虑移植问题——Java 本身就是一种“与平台无关”的语言。
3。1。15 复习计算顺序
在我举办的一次培训班中,有人抱怨运算符的优先顺序太难记了。一名学生推荐用一句话来帮助记忆:
“Ulcer Addicts Really Like C A lot”,即“溃疡患者特别喜欢(维生素)C”。
助记词 运算符类型 运算符
Ulcer (溃疡) Unary:一元 + + + '' 其余的 ''
Addicts (患者) Arithmetic(shift) ;算术(和移位) * / % + 》
Really (特别) Relational:关系 》 《 》= B ? X:Y
A Lot Assignment:赋值 = (以及复合赋值,如*=)
当然,对于移位和按位运算符,上表并不是完美的助记方法;但对于其他运算来说,它确实很管用。
3。1。16 运算符总结
下面这个例子向大家展示了如何随同特定的运算符使用主数据类型。从根本上说,它是同一个例子反反复复
地执行,只是使用了不同的主数据类型。文件编译时不会报错,因为那些会导致错误的行已用//!变成了注释
内容。
//: AllOps。java
// Tests all the operators on all the
// primitive data types to show which
// ones are accepted by the Java piler。
class AllOps {
// To accept the results of a boolean test:
void f(boolean b) {}
void boolTest(boolean x; boolean y) {
// Arithmetic operators:
//! x = x * y;
//! x = x / y;
//! x = x % y;
//! x = x + y;
//! x = x y;
//! x++;
//! x……;
//! x = +y;
//! x = …y;
// Relational and logical:
//! f(x 》 y);
//! f(x 》= y);
//! f(x 《 y);
//! f(x 1;
//! x = x 》》》 1;
// pound assignment:
//! x += y;
//! x …= y;
//! x *= y;
//! x /= y;
//! x %= y;
//! x = 1;
//! x 》》》= 1;
x &= y;
x ^= y;
x |= y;
// Casting:
//! char c = (char)x;
//! byte B = (byte)x;
//! short s = (short)x;
//! int i = (int)x;
//! long l = (long)x;
//! float f = (float)x;
//! double d = (double)x;
}
void charTest(char x; char y) {
// Arithmetic operators:
x = (char)(x * y);
x = (char)(x / y);
x = (char)(x % y);
x = (char)(x + y);
x = (char)(x y);
x++;
x……;
x = (char)+y;
x = (char)…y;
// Relational and logical:
f(x 》 y);
f(x 》= y);
f(x 《 y);
f(x 1);
x = (char)(x 》》》 1);
// pound assignment:
x += y;
x …= y;
x *= y;
x /= y;
x %= y;
x = 1;
x 》》》= 1;
x &= y;
x ^= y;
x |= y;
// Casting:
//! boolean b = (boolean)x;
byte B = (byte)x;
short s = (short)x;
int i = (int)x;
long l = (long)x;
float f = (float)x;
double d = (double)x;
}
void byteTest(byte x; byte y) {
// Arithmetic operators:
x = (byte)(x* y);
x = (byte)(x / y);
x = (byte)(x % y);
x = (byte)(x + y);
x = (byte)(x y);
x++;
x……;
x = (byte)+ y;
x = (byte)y;
// Relational and logical:
f(x 》 y);
f(x 》= y);
f(x 《 y);
f(x 1);
x = (byte)(x 》》》 1);
// pound assignment:
x += y;
x …= y;
x *= y;
x /= y;
x %= y;
x = 1;
x 》》》= 1;
x &= y;
x ^= y;
x |= y;
// Casting:
//! boolean b = (boolean)x;
char c = (char)x;
short s = (short)x;
int i = (int)x;
long l = (long)x;
float f = (float)x;
double d = (double)x;
}
void shortTest(short x; short y) {
// Arithmetic operators:
x = (short)(x * y);
x = (short)(x / y);
x = (short)(x % y);
x = (short)(x + y);
x = (short)(x y);
x++;
x……;
x = (short)+y;
x = (short)…y;
// Relational and logical:
f(x 》 y);
f(x 》= y);
f(x 《 y);
f(x 1);
x = (short)(x 》》》 1);
// pound assignment:
x += y;
x …= y;
x *= y;
x /= y;
x %= y;
x = 1;
x 》》》= 1;
x &= y;
x ^= y;
x |= y;
// Casting:
//! boolean b = (boolean)x;
char c = (char)x;
byte B = (byte)x;
int i = (int)x;
long l = (long)x;
float f = (float)x;
double d = (double)x;
}
void intTest(int x; int y) {
// Arithmetic operators:
x = x * y;
x = x / y;
x = x % y;
x = x + y;
x = x y;
x++;
x……;
x = +y;
x = …y;
// Relational and logical:
f(x 》 y);
f(x 》= y);
f(x 《 y);
f(x 1;
x = x 》》》 1;
// pound assignment:
x += y;
x …= y;
x *= y;
x /= y;
x %= y;
x = 1;
x 》》》= 1;
x &= y;
x ^= y;
x |= y;
// Casting:
//! boolean b = (boolean)x;
char c = (char)x;
byte B = (byte)x;
short s = (short)x;
long l = (long)x;
float f = (float)x;
double d = (double)x;
}
void longTest(long x; long y) {
// Arithmetic operators:
x = x * y;
x = x / y;
x = x % y;
x = x + y;
x = x y;
x++;
x……;
x = +y;
x = …y;
// Relational and logical:
f(x 》 y);
f(x 》= y);
f(x 《 y);
f(x 1;
x = x 》》》 1;
// pound assignment:
x += y;
x …= y;
x *= y;
x /= y;
x %= y;
x = 1;
x 》》》= 1;
x &= y;
x ^= y;
x |= y;
// Casting:
//! boolean b = (boolean)x;
char c = (char)x;
byte B = (byte)x;
short s = (short)x;
int i = (int)x;
float f = (float)x;
double d = (double)x;
}
void floatTest(float x; float y) {
// Arithmetic operators:
x = x * y;
x = x / y;
x = x % y;
x = x + y;
x = x y;
x++;
x……;
x = +y;
x = …y;
// Relational and logical:
f(x 》 y);
f(x 》= y);
f(x 《 y);
f(x 1;
//! x = x 》》》 1;
81
…………………………………………………………Page 83……………………………………………………………
// pound assignment:
x += y;
x …= y;
x *= y;
x /= y;
x %= y;
//! x = 1;
//! x 》》》= 1;
//! x &= y;
//! x ^= y;
//! x |= y;
// Casting:
//! boolean b = (boolean)x;
char c = (char)x;
byte B = (byte)x;
short s = (short)x;
int i = (int)x;
long l = (long)x;
double d = (double)x;
}
void doubleTest(double x; double y) {
// Arithmetic operators:
x = x * y;
x = x / y;
x = x % y;
x = x + y;
x = x y;
x++;
x……;
x = +y;
x = …y;
// Relational and logical:
f(x 》 y);
f(x 》= y);
f(x 《 y);
f(x 1;
//! x = x 》》》 1;
// pound assignment:
x += y;
82
…………………………………………………………Page 84……………………………………………………………
x …= y;
x *= y;
x /= y;
x %= y;
//! x = 1;
//! x 》》》= 1;
//! x &= y;
//! x ^= y;
//! x |= y;
// Casting:
//! boolean b = (boolean)x;
char c = (char)x;
byte B = (byte)x;
short s = (short)x;
int i = (int)x;
long l = (long)x;
float f = (float)x;
}
} ///:~
注意布尔值(boolean)的能力非常有限。我们只能为其赋予true 和false 值。而且可测试它为真还是为
假,但不可为它们再添加布尔值,或进行其他其他任何类型运算。
在 char,byte 和 short 中,我们可看到算术运算符的“转型”效果。对这些类型的任何一个进行算术运算,
都会获得一个 int 结果。必须将其明确“造型”回原来的类型(缩小转换会造成信息的丢失),以便将值赋
回那个类型。但对于int值,却不必进行造型处理,因为所有数据都已经属于 int类型。然而,不要放松警
惕,认为一切事情都是安全的。如果对两个足够大的 int 值执行乘法运算,结果值就会溢出。下面这个例子
向大家展示了这一点�
快捷操作: 按键盘上方向键 ← 或 → 可快速上下翻页 按键盘上的 Enter 键可回到本书目录页 按键盘上方向键 ↑ 可回到本页顶部!
温馨提示: 温看小说的同时发表评论,说出自己的看法和其它小伙伴们分享也不错哦!发表书评还可以获得积分和经验奖励,认真写原创书评 被采纳为精评可以获得大量金币、积分和经验奖励哦!