Java2实用教程(第5版微课版高等学校Java课程系列教材)

Java2实用教程(第5版微课版高等学校Java课程系列教材)
作者: 编者:耿祥义//张跃平
出版社: 清华大学
原售价: 59.50
折扣价: 45.30
折扣购买: Java2实用教程(第5版微课版高等学校Java课程系列教材)
ISBN: 9787302464259

作者简介

耿释义,1995年中国科学技术大学博士毕业,获理学博士学位。1997年从中山大学博士后流动站出站。现任大连交通大学教授。有多年讲授Java语言的经验,已编写出版十余部教材。

内容简介

第3章 运算符、表达式和语句   主要内容 ? 运算符与表达式 ? 语句概述 ? if条件分支语句 ? switch开关语句 ? 循环语句 ? break和continue语句 ? 数组与for语句 3.1 运算符与表达式   Java提供了丰富的运算符,如算术运算符、关系运算符、逻辑运算符、位运算符等。Java语言中的绝大多数运算符和C语言相同,基本语句如条件分支语句、循环语句等也和C语言类似,因此,本章就主要知识点给予简单的介绍。 3.1.1 算术运算符与算术表达式   加减运算符   加减运算符+,–是二目运算符,即连接两个操作元的运算符。加减运算符的结合方向是从左到右。例如2+3–8,先计算2+3,然后再将得到的结果减8。加减运算符的操作元是整型或浮点型数据,加减运算符的优先级是4级。   乘、除和求余运算符   乘、除和求余运算符*、/、%是二目运算符,结合方向是从左到右,例如2*3/8,先计算2*3,然后再将得到的结果除以8。乘,除和求余运算符的操作元是整型或浮点型数据,*、/、%运算符的优先级是3级。   用算术运算符和括号连接起来的符合Java语法规则的式子,称为算术表达式。如x+2*y–30+3*(y+5)。 3.1.2 自增、自减运算符   自增、自减运算符++、–?–是单目运算符,可以放在操作元之前,也可以放在操作元之后。操作元必须是一个整型或浮点型变量,作用是使变量的值增1或减1,例如:   ++x(–?–x)表示在使用x之前,先使x的值增(减)1。   x++(x–?–)表示在使用x之后,使x的值增(减)1。   粗略地看,++x和x++的作用相当于x = x+1。但++x和x++的不同之处在于,++x是先执行x = x+1再使用x的值,而x++是先使用x的值再执行x = x+1。如果x的原值是5,则对于“y = ++x;”,y的值为6,对于“y = x++;”,y的值为5。 3.1.3 算术混合运算的精度   精度从“低”到“高”排列的顺序是:   byte short char int long float double。   Java在计算算术表达式的值时,使用下列运算精度规则:   (1)如果表达式中有双精度浮点数(double型数据),则按双精度进行运算。例如,表达式5.0/2+10的结果12.5是double型数据。   (2)如果表达式中最高精度是单精度浮点数(float型数据),则按单精度进行运算。例如,表达式5.0F/2+10的结果12.5是float型数据。   (3)如果表达式中最高精度是long型整数,则按long精度进行运算。例如,表达式12L+100+'a'的结果209是long型数据。   (4)如果表达式中最高精度低于int型整数,则按int精度进行运算。例如,表达式(byte)10+'a'和5/2的结果分别为107和2,都是int型数据。   Java允许把不超出byte、short和char的取值范围的算术表达式的值赋给byte、short和char型变量。例如,(byte)30+'a'是结果为127的int型常量,    byte x =(byte)20+'a';    是正确的,但    byte x=(byte)30+'b';      却无法通过编译,编译错误是“可能损失精度,找到int需要byte”,其原因是(byte)30+'b'的结果是int型常量,其值超出了byte变量的取值范围(见上面关于运算精度的讲述(4))。 3.1.4 关系运算符与关系表达式   关系运算符是二目运算符,用来比较两个值的关系。关系运算符的运算结果是boolean型,当运算符对应的关系成立时,运算结果是true,否则是false。例如,10<9的结果是false,5>1的结果是true,3!=5的结果是true,10>20–17的结果为true,因为算术运算符的级别高于关系运算符,10>20–17相当于10>(20–17),其结果是true。   结果为数值型的变量或表达式可以通过关系运算符(如表3.1所示)形成关系表达式。例如4>8,(x+y)>80等。 表3.1 关系运算符 运算符 优先级 用法 含义 结合方向 > < >= <= == != 6 6 6 6 7 7 op1>op2 op1=op2 op1<=op2 op1==op2 op1!=op2 大于 小于 大于等于 小于等于 等于 不等于 左到右 左到右 左到右 左到右 左到右 左到右 3.1.5 逻辑运算符与逻辑表达式   逻辑运算符包括&&、||、!。其中&&、||为二目运算符,实现逻辑与、逻辑或;!为单目运算符,实现逻辑非。逻辑运算符的操作元必须是boolean型数据,逻辑运算符可以用来连接关系表达式。   表3.2给出了逻辑运算符的用法和含义。 表3.2 逻辑运算符 运算符 优先级 用法 含义 结合方向 && || ! 11 12 2 op1&&op2 op1||op2 !op 逻辑与 逻辑或 逻辑非 左到右 左到右 右到左      结果为boolean型的变量或表达式可以通过逻辑运算符形成逻辑表达式。表3.3给出了用逻辑运算符进行逻辑运算的结果。 表3.3 用逻辑运算符进行逻辑运算 op1 op2 op1&&op2 op1||op2 !op1 true true true true false true false false true false false true false true true false false false false true      例如,2>8&&9>2的结果为false,2>8||9>2的结果为true。由于关系运算符的级别高于&&、||的级别,2>8&&8>2相当于(2>8)&&(9>2)。   逻辑运算符&&和||也称作短路逻辑运算符,这是因为当op1的值是false时,&&运算符在进行运算时不再去计算op2的值,直接就得出op1&&op2的结果是false;当op1的值是true时,||运算符在进行运算时不再去计算op2的值,直接就得出op1||op2的结果是true。 3.1.6 赋值运算符与赋值表达式   赋值运算符=是二目运算符,左面的操作元必须是变量,不能是常量或表达式。设x是一个整型变量,y是一个boolean型变量,x = 20和y = true都是正确的赋值表达式,赋值运算符的优先级较低,是14级,结合方向是从右到左。   赋值表达式的值就是=左面变量的值。例如,假如a、b是两个int型变量,那么表达式b = 12和a = b = 100的值分别是12和100。   注意不要将赋值运算符=与等号关系运算符==混淆,例如,12 = 12是非法的表达式,而表达式12 == 12的值是true。 3.1.7 位运算符   整型数据在内存中以二进制的形式表示,例如一个int型变量在内存中占4个字节共32位,int型数据7的二进制表示是:    00000000 00000000 00000000 00000111      左面最高位是符号位,最高位是0表示正数,是1表示负数。负数采用补码表示,例如–8的补码表示是:    111111111 111111111 1111111 11111000   这样就可以对两个整型数据实施位运算,即对两个整型数据对应的位进行运算得到一个新的整型数据。   按位与运算   按位与运算符&是双目运算符,对两个整型数据a、b按位进行运算,运算结果是一个整型数据c。运算法则是:如果a、b两个数据对应位都是1,则c的该位是1,否则是0。如果b的精度高于a,那么结果c的精度和b相同。   例如:    a:00000000 00000000 00000000 00000111   & b:10000001 10100101 11110011 10101011    c:00000000 00000000 00000000 00000011   按位或运算   按位或运算符|是二目运算符,对两个整型数据a、b按位进行运算,运算结果是一个整型数据c。运算法则是:如果a、b两个数据对应位都是0,则c的该位是0,否则是1。如果b的精度高于a,那么结果c的精度和b相同。   按位非运算   按位非运算符~是单目运算符,对一个整型数据a按位进行运算,运算结果是一个整型数据c。运算法则是:如果a对应位是0,则c的该位是1,否则是0。   按位异或运算   按位异或运算符^是二目运算符,对两个整型数据a、b按位进行运算,运算结果是一个整型数据c。运算法则是:如果a、b两个数据对应位相同,则c的该位是0,否则是1。如果b的精度高于a,那么结果c的精度和b相同。   由异或运算法则可知:a^a=0,a^0=a。   因此,如果c=a^b,那么a=c^b,也就是说,^的逆运算仍然是^,即a^b^b等于a。   位运算符也可以操作逻辑型数据,法则是:   当a、b都是true时,a&b是true,否则a&b是false。   当a、b都是false时,a|b是false,否则a|b是true。   当a是true时,~a是false;当a是false时,~a是true。   位运算符在操作逻辑型数据时,与逻辑运算符&&、||、!不同的是:位运算符要计算完a和b的值之后再给出运算的结果。例如,x的初值是1,那么经过下列逻辑比较运算后,    ((y=1)==0))&&((x=6)==6));      x的值仍然是1,但是如果经过下列位运算之后,    ((y=1)==0))&((x=6)==6));      x的值将是6。   在下面的例子1中,利用异或运算的性质,对几个字符进行加密并输出密文,然后再解密,运行效果如图3.1所示。 例子1   Example3_1.java public class Example3_1 { public static void main(String args[]) { char a1 = '十',a2 = '点',a3 = '进',a4 = '攻'; char secret = 'A'; a1 = (char)(a1^secret); a2 = (char)(a2^secret); a3 = (char)(a3^secret); a4 = (char)(a4^secret); System.out.println(\"密文:\"+a1+a2+a3+a4); a1 = (char)(a1^secret); a2 = (char)(a2^secret); a3 = (char)(a3^secret; a4 = (char)(a4^secret); System.out.println(\"原文:\"+a1+a2+a3+a4); } } 3.1.8 instanceof运算符   该运算符是二目运算符,左面的操作元是一个对象,右面是一个类。当左面的对象是右面的类或子类创建的对象时,该运算符运算的结果是true,否则是false(有关细节详见 5.3.2节)。 3.1.9 运算符综述   Java表达式就是用运算符连接起来的符合Java规则的式子。运算符的优先级决定了表达式中运算执行的先后顺序。例如,x> << >>> 左到右 6 大小关系运算 < <= > >= 左到右 7 相等关系运算 == != 左到右 8 按位与运算 & 左到右 9 按位异或运算 ^ 左到右 10 按位或 | 左到右 11 逻辑与运算 && 左到右 12 逻辑或运算 || 左到右 13 三目条件运算 ? : 左到右 14 赋值运算 = 右到左 3.2 语句概述   Java里的语句可分为以下6类。   方法调用语句   如:    System.out.println(\"Hello\");      表达式语句   由一个表达式构成一个语句,即表达式尾加上分号。例如赋值语句:    x = 23;      复合语句   可以用{ }把一些语句括起来构成复合语句,例如:    { z = 123+x; System.out.println(\"How are you\"); }      空语句   一个分号也是一条语句,称作空语句。   控制语句   控制语句分为条件分支语句、开关语句和循环语句,将在后面的3.3~3.5节介绍。   package语句和import语句   package语句和import语句与类、对象有关,将在第4章讲解。 3.3 if条件分支语句   条件分支语句按语法格式可细分为三种形式,以下是这三种形式的详细讲解。 3.3.1 if语句   if语句是单条件单分支语句,即根据一个条件来控制程序执行的流程。   if语句的语法格式:    if(表达式){ 若干语句 }      if语句的流程图如图3.2所示。在if语句中,关键字if后面的一对小括号()内的表达式的值必须是boolean类型,当值为true时,则执行紧跟着的复合语句,结束当前if语句的执行;如果表达式的值为false,结束当前if语句的执行。   需要注意的是,在if语句中,其中的复合语句中如果只有一条语句,{}可以省略不写,但为了增强程序的可读性最好不要省略(这是一个很好的编程风格)。   在下面的例子2中,将变量a、b、c中的数值按大小顺序进行互换(从小到大排列)。 例子2   Example3_2.java    public class Example3_2 { public static void main(String args[]) { int a = 9,b = 5,c = 7,t=0; if(b0) y=10; z=20; else y=-100;      正确的写法是:    if(x>0){ y=10; z=20; } else y=100;      需要注意的是,在if-else语句中,其中的复合语句中如果只有一条语句,{}可以省略不写,但为了增强程序的可读性最好不要省略(这是一个很好的编程风格)。   例子3中有两条if-else语句,其作用是根据成绩输出相应的信息,运行效果如图3.4 所示。 例子3   Example3_3.java    public class Example3_3 { public static void main(String args[]) { int math = 65 ,english = 85; if(math>60) { System.out.println(\"数学及格了\"); } else { System.out.println(\"数学不及格\"); } if(english>90) { System.out.println(\"英语是优\"); } else { System.out.println(\"英语不是优\"); } System.out.println(\"我在学习if-else语句\"); } } 3.3.3 if-else if-else语句   if-else if-else语句是多条件分支语句,即根据多个条件来控制程序执行的流程。   if-else if-else语句的语法格式:    if(表达式) { 若干语句 } else if(表达式) { 若干语句 } ( else { 若干语句 }      if-else if-else语句的流程图如图3.5所示。在if-else if-else语句中,if以及多个else if后面的一对小括号()内的表达式的值必须是boolean类型。程序执行if-else if-else时,按该语句中表达式的顺序,首先计算第1个表达式的值,如果计算结果为true,则执行紧跟着的复合语句,结束当前if-else if-else语句的执行,如果计算结果为false,则继续计算第2个表达式的值,依次类推,假设计算第m个表达式的值为true,则执行紧跟着的复合语句,结束当前if-else if-else语句的执行,否则继续计算第m+1个表达式的值,如果所有表达式的值都为false,则执行关键字else后面的复合语句,结束当前if-else if-else语句的执行。 图3.5 if-else if-else多条件、多分支语句   if-else if-else语句中的else部分是可选项,如果没有else部分,当所有表达式的值都为false时,结束当前if-else if-else语句的执行(该语句什么都没有做)。   需要注意的是,在if-else if-else语句中,其中的复合语句中如果只有一条语句,{}可以省略不写,但为了增强程序的可读性最好不要省略。 3.4 switch开关语句   switch语句是单条件多分支的开关语句,它的一般格式定义如下(其中break语句是可选的)。 switch(表达式) { case 常量值1: 若干个语句 break; case 常量值2: 若干个语句 break; ( case 常量值n: 若干个语句 break; default: 若干语句 }      switch语句中“表达式”的值可以为byte、short、int、char型;“常量值1”到“常量值n”也是byte、short、int、char型,而且要互不相同。   switch语句首先计算表达式的值,如果表达式的值和某个case后面的常量值相等,就执行该case里的若干个语句直到碰到break语句为止。如果某个case中没有使用break语句,一旦表达式的值和该case 后面的常量值相等,程序不仅执行该case里的若干个语句,而且继续执行后继的case里的若干个语句,直到碰到break语句为止。若switch语句中的表达式的值不与任何case的常量值相等,则执行default后面的若干个语句。switch语句中的default是可选的,如果它不存在,并且switch语句中表达式的值不与任何case的常量值相等,那么switch语句就不会进行任何处理。   前面学习的分支语句(if语句、if-else语句和if-else if-else语句)的共同特点是根据一个条件选择执行一个分支操作,而不是选择执行多个分支操作。在switch语句中,通过合理地使用break语句,可以达到根据一个条件选择执行一个分支操作(一个case)或多个分支操作(多个case)的结果。   下面的例子4使用了switch语句判断用户从键盘输入的正整数是否为中奖号码。 例子4   Example3_4.java    import java.util.Scanner; public class Example3_4{ public static void main(String args[]) { int number = 0; System.out.println(\"输入正整数(回车确定)\"); Scanner reader = new Scanner(System.in); number = reader.nextInt(); switch(number) { case 9 : case 131 : case 12 : System.out.println(number+\"是三等奖\"); break; case 209 : case 596 : case 27 : System.out.println(number+\"是二等奖\"); break; case 875 : case 316 : case 59 : System.out.println(number+\"是一等奖\"); break; default: System.out.println(number+\"未中奖\"); } } }      需要强调的是,switch语句中表达式的值可以是byte、short、int、char型,但不可以是long型数据。如果将例子4中的    int number = 0;    更改为    long number = 0;    将导致编译错误。 3.5 循环语句   循环语句是根据条件,要求程序反复执行某些操作,直到程序“满意”为止。 3.5.1 for循环语句   for语句的语法格式:    for (表达式1; 表达式2; 表达式3) { 若干语句 }      for语句由关键字for、一对小括号()中用分号分割的三个表达式,以及一个复合语句组成,其中的表达式2必须是一个求值为boolean型数据的表达式,而复合语句称作循环体。循环体只有一条语句时,大括号{}可以省略,但最好不要省略,以便增加程序的可读性。表达式1负责完成变量的初始化;表达式2是值为boolean型的表达式,称为循环条件;表达式3用来修整变量,改变循环条件。for语句的执行规则是:   (1)计算表达式1,完成必要的初始化工作。   (2)判断表达式2的值,若表达式2的值为true,则进行(3),否则进行(4)。   (3)执行循环体,然后计算表达式3,以便改变循环条件,进行(2)。   (4)结束for语句的执行。   for语句执行流程如图3.6所示。   下面的例子5计算8+88+888+8888+…的前12项和。 例子5   Example3_5.java    public class Example3_5 { public static void main(String args[]) { long sum = 0,a = 8,item = a,n = 12,i = 1; for(i=1;i<=n;i++) { sum = sum+item; item = item*10+a; } System.out.println(sum); } } 3.5.2 while循环语句   while语句的语法格式:    while(表达式) { 若干语句 }      while语句由关键字while、一对括号()中的一个求值为boolean类型数据的表达式和一个复合语句组成,其中的复合语句称为循环体,循环体只有一条语句时,大括号{}可以省略,但最好不要省略,以便增加程序的可读性。表达式称为循环条件。while语句的执行规则是:   (1)计算表达式的值,如果该值是true时,就进行(2),否则执行(3)。   (2)执行循环体,再进行(1)。   (3)结束while语句的执行。   while语句执行流程如图3.7所示。 图3.7 while循环语句 图3.8 do-while循环语句 3.5.3 do-while循环语句   do-while循环语法格式如下:    do{ 若干语句 }while(表达式);      do-while循环和while循环的区别是do-while的循环体至少被执行一次,执行流程如图3.8所示。   下面的例子6用while语句计算1+1/2!+1/3!+1/4!+… 的前20项和。 例子6   Example3_6.java    public class Example3_6 { public static void main(String args[]) { double sum = 0,item = 1; int i = 1,n = 20; while(i<=n) { sum = sum+item; i = i+1; item = item*(1.0/i); } System.out.println(\"sum=\"+sum); } } 3.6 break和continue语句   break和continue语句是用关键字break或continue加上分号构成的语句,例如:    break;      在循环体中可以使用break语句和continue语句。在一个循环中,例如循环50次的循环语句中,如果在某次循环中执行了break语句,那么整个循环语句就结束。如果在某次循环中执行了continue语句,那么本次循环就结束,即不再执行本次循环中循环体中continue语句后面的语句,而转入进行下一次循环。   下面的例子7使用了break和continue语句。 例子7   Example3_7.java    public class Example3_7 { public static void main(String args[]) { int sum=0,i,j; for( i=1;i<=10;i++) { if(i%2==0) { //计算1+3+5+7+9 continue; } sum=sum+i; } System.out.println(\"sum=\"+sum); for(j=2;j<=100;j++) { //求100以内的素数 for( i=2;i<=j/2;i++) { if(j%i==0) break; } if(i>j/2) { System.out.println(\"\"+j+\"是素数\"); } } } } 3.7 for语句与数组   JDK 1.5对for语句的功能给予扩充、增强,以便更好地遍历数组。语法格式如下:    for(声明循环变量:数组的名字) { … }      其中,声明的循环变量的类型必须和数组的类型相同。这种形式的for语句类似自然语言中的“for each”语句,为了便于理解上述for语句,可以将这种形式的for语句翻译成“对于循环变量依次取数组的每一个元素的值”。   下面的例子8分别使用for语句的传统方式和改进方式遍历数组。 例子8   Example3_8.java    public class Example3_8 { public static void main(String args[]) { int a[] = {1,2,3,4}; char b[] = {'a','b','c','d'}; for(int n=0;n0 B.m++>0 C.m = 0 D.m>100&&true    public class E { public static void main (String args[ ]) { int m=10,n=0; while(【代码】) { n++; } } }      (3)假设有“int x=1;”,以下哪个代码导致“可能损失精度,找到int需要char”这样的编译错误?     A.short t=12+'a'; B.char c ='a'+1;    C.char m ='a'+x; D.byte n ='a'+1;   3.阅读程序   (1)下列程序的输出结果是什么?    public class E { public static void main (String args[ ]) { char x='你',y='e',z='吃'; if(x>'A'){ y='苹'; z='果'; } else y='酸'; z='甜'; System.out.println(x+\",\"+y+\",\"+z); } }      (2)下列程序的输出结果是什么?    public class E { public static void main (String args[ ]) { char c = '\\0'; for(int i=1;i<=4;i++) { switch(i) { case 1: c = 'J'; System.out.print(c); case 2: c = 'e'; System.out.print(c); break; case 3: c = 'p'; System.out.print(c); default: System.out.print(\"好\"); } } } }      (3)下列程序的输出结果是什么?    public class E { public static void main (String []args) { int x = 1,y = 6; while (y-->0) { x--; } System.out.print(\"x=\"+x+\",y=\"+y); } }      4.编程题   (1)编写应用程序求1!+2!+…+10!。   (2)编写一个应用程序求100以内的全部素数。   (3)分别用do-while和for循环计算1+1/2!+1/3!+1/4!+…的前20项和。   (4)一个数如果恰好等于它的因子之和,这个数就称为完数。编写应用程序求1000之内的所有完数。   (5)编写应用程序,使用for循环语句计算8+88+888+…前10项之和。   (6)编写应用程序,输出满足1+2+3+…+n<8888的最大正整数n。 ?? ?? ?? ?? Java 2实用教程 第3章 运算符、表达式和语句 基础与实战。相关概念及知识点都辅以相应的实例,通俗易懂,便于理解掌握面向对象的编程思想。 实用与流行。涵盖了Java开发过程中重要的及流行的方法和技巧,讲解细致,环环相扣。 教学与互动。文字叙述注重可读性,知识组织注意合理性,提供辅助在线教学平台。