02_Java基本语法_4
2.2.10.1.6 条件运算符
条件运算就是三目运算符,一般形式:A1 ? A2 : A3;表示若A1为真,则执行A2,否则执行A3。如表2-13所示:
表2-13 条件运算符
条件运算符替换if…else结构如图2-7所示:
图2-7 条件表达式运算过程
下面的这个程序是求两个数的最大值。
范例:TestJava2_21.java
//下面这段程序是求两个数的最大值 public class TestJava2_21 { public static void main(String[] args) { int a = 10; int b = 20; int max = a > b ? a : b; System.out.println("max = " + max); } }
2.2.10.1.7 括号运算符
除了前面所述的内容外,括号()也是Java的运算符,如表2-14所示:
表2-14 括号运算符
括号运算符()是用来处理表达式的优先级的。以一个简单的加减乘除式子为例:
3+5+4*6-7 //未加括号的表达式,结果为25
如果想先计算3+5+4及6-7之后再将两数相乘时,就必须将3+5+4及6-7分别加上括号,而成为下面的式子:
(3+5+4)*(6-7) //加上括号的表达式
经过括号运算符()的运作后,计算结果为-12,所以括号运算符()可以使括号内表达式的处理顺序优先。
2.2.10.1.8 位运算符
Java编程语言支持整数数据类型的位运算,如表2-15所示:
表2-15 位运算
按位与(&):当两边操作数的位同时为1时,结果为1,否则为0。如1100&1010=1000
按位或(|):当两边操作数的位同时为0时,结果为0,否则为1。如1100|1010=1110
按位取反(~):0变1,1变0。公式:一个数按位取反之后的值为原数据的相反数-1
按位异或(^):相同为0,相异为1。如1100^1010=0110
左移(<<):将值左移规定的次数,低位补0。它的通用格式为:
value << num//num表示左移的次数
左移的规则只记住一点:丢弃最高位,最低位补0
如果移动的位数超过了该类型的最大位数,那么编译器会对移动的位数取模。如对int型移动33位,实际上只移动了33%32=1位。在数字没有溢出的前提下,对于正数和负数,左移一位都相当于乘以2的1次方,左移n位就相当于乘以2的n次方。
例如:3 << 2(3为int型)
1)把3转换为二进制数字0000 0000 0000 0000 0000 0000 0000 0011
2)把该数字高位(左侧)的两个零移出,其他的数字都朝左平移2位
3)在低位(右侧)的两个空位补零。则得到的最终结果是:0000 0000 0000 0000 0000 0000 0000 1100。转换为十进制是12。
符号右移(>>):将值右移规定的次数,最高位补符号位。它的通用格式为:
value >> num //num表示右移的次数
右移的规则只记住一点:符号位不变,左边补上符号位
右移一位相当于除2,右移n位相当于除以2的n次方。
例如:35 >> 2 (35为int型)
1)35转换为二进制:0000 0000 0000 0000 0000 0000 0010 0011
2)把低位的最后两个数字移出,因为该数字是正数,所以在高位补零
3)最终结果为:0000 0000 0000 0000 0000 0000 0000 1000。转换为十进制:8。
不带符号右移(>>>):将值右移规定的次数,最高位补0。它的通用格式为:
value >>> num //num表示右移的次数
无符号右移的规则只记住一点:忽略了符号位扩展,最高位补0。
无符号右移运算符只是对32位和64位的值有意义。
2.2.10.1.9 字符串连接运算符
程序中将使用“"”括起来的代码称为字符串。字符串的连接使用“+”。
“+”运算符两侧的操作数只要一个是字符串(String)类型,系统会自动将另外一个操作数转换为字符串然后进行联接。例如:
int iNo = 1001;
System.out.println("学号为:" + iNo);
2.2.10.2 运算符的优先级
表2-16列出了各个运算符的优先级的排列,数字越小的表示优先级越高。
表2-16 运算符的优先级
表2-16的最后一栏是运算符的结合性。什么是结合性呢?结合性可以让程序设计者了解到运算符与操作数之间的关系及其相对位置。举例来说,当使用同一优先级的运算符时,结合性就非常重要了,它决定谁会先被处理。可以看看下面的例子:
a = b + d / 5 * 4;
这个表达式中含有不同优先级的运算符,其中是“/”与“*”的优先级高于“+”,而“+”又高于“=”,但是“/”与“*”的优先级是相同的,到底d该先除以5再乘以4呢?还是5乘以4后d再除以这个结果呢?结合性的定义,就解决了这方面的困扰,算术运算符的结合性为“由左至右”,就是在相同优先级的运算符中,先由运算符左边的操作数开始处理,再处理右边的操作数。上面的式子中,由于“/”与“*”的优先级相同,因此d会先除以5再乘以4得到的结果如上b后,将整个值赋给a存放。
2.2.10.3 表达式
Java中的语句有很多种形式,表达式就是其中一种形式。表达式是由运算符和操作数组成。操作数可以是常量、变量也可以是方法,而运算符就是数学中的运算符号,如“+”、“-”、“*”、“/”、“%”等。以下面的表达式(z+100)为例,“z”与“100”都是操作数,而“+”就是运算符。
图2-8 表达式是由操作数与运算符所组成
如下面例子,均是表达式正确的使用方法:
-49 // 表达式由一元运算符“-”与常量49组成
sum + 2 // 表达式由变量sum、算术运算符与常量2组成
a + b–c / ( d * 3–9 ) // 表达式由变量、常量与运算符所组成
此外,Java还有一些相当简洁的写法,是将算术运算符和赋值运算符结合成为新的运算符,表2-17列出了一些运算符。
表2-17 简洁的表达式
下面的几个表达式,皆是简洁的写法:
a++ // 相当于 a = a + 1
a -= 5 // 相当于 a = a – 5
b %= c// 相当于 b = b % c
a /= b--// 相当于计算 a = a / b 之后,再计算b--
这种独特的写法虽然看起来有些怪异,但是它却可以减少程序的行数,提高运行的速度!看下面这道范例:
范例:TestJava2_22.java
//下面是关于简洁写法的一段程序 public class TestJava2_22 { public static void main(String[] args) { int a = 5, b = 8; System.out.println("改变之前的数是: a = " + a + " , b = " + b); a += b; System.out.println("改变之后的数是: a = " + a + " , b = " + b); } }
输出结果:
改变之前的数是: a = 5 , b = 8
改变之后的数是: a = 13 , b = 8
程序说明:
1、第6行分别把变量a、b赋值为5及8。
2、第7行在运算之前先输出变量a、b的值,a为5,b为8。
3、第8行计算a+=b,这个语句也就相当于a = a +b,将a+b的值存放到a中。计算5+8的结果后赋值给a存放。
4、程序第9行,再输出运算之后变量a、b的值。所以a的值变成13,而b仍为8。
除了前面所提到的算术运算符和赋值运算符的结合可以存在于简洁的表达式中,递增、递减运算符也同样可以应用在简洁的表达式中。表2-17列出了一些简洁写法的运算符及其范例说明。
表2-17 简洁表达式的范例
举一个实例来说明这些简洁的表达式在程序中该如何应用。以TestJava2_23为例,输入两个数,经过运算之后,来看看这两个变量所存放的值有什么变化。
范例:TestJava2_23.java
//下面的程序说明了简洁表达式的使用方法,但这种方式现在已不提倡使用了。 public class TestJava2_23 { public static void main(String[] args) { int a = 10, b = 6; System.out.println("改变之前的数: a = " + a + " , b = " + b); a -= b++; // 先计算a-b的值,将结果设给a之后,再将b值加1 System.out.println("改变之后的数: a = " + a + " , b = " + b); } }
输出结果:
改变之前的数: a = 10 , b = 6
改变之后的数: a = 4 , b = 7
程序说明:
1、第7行输出运算前变量a、b的值。在程序中a、b的赋值为10、6,因此输出的结果a为10,b为6。
2、第8行计算a -= b++,也就是执行下面这两个语句:
a = a - b ; //(a = 10 - 6 = 4,所以a = 4)
b++ ; //(b = b+1 = 6+1 = 7 ,所以b = 7)
3、程序第9行,将经过运算之后的结果输出,即可得到a为4,b为7的答案
2.2.10.4 表达式的类型转换
当int类型遇上了float类型,到底谁是“赢家”呢?在前面曾提到过数据类型的转换,在这里,要再一次详细讨论表达式的类型转换。
Java是一个很有弹性的程序设计语言,当上述的情况发生时,只要坚持“以不流失数据为前提”的大原则,即可做不同的类型转换,使不同类型的数据、表达式都能继续存储。依照大原则,当Java发现程序的表达式中有类型不相符的情况时,会依据下列的规则来处理类型的转换。
1、占用字节较少的类型转换成占用字节较多的类型。
2、字符类型会转换成int类型。
3、int类型会转换成float类型。
4、表达式中若某个操作数的类型为double,则另一个操作数也会转换成double类型。
5、布尔类型不能转换成其它类型。
范例:TestJava2_24.java
//下面的程序说明了表达式类型的自动转换问题 public class TestJava2_24 { public static void main(String[] args) { char ch = 'a'; short a = -2; int b = 3; float f = 5.3f; double d = 6.28; System.out.print("(ch / a) - (d / f) - (a + b) = "); System.out.println((ch / a) - (d / f) - (a + b)); } }
输出结果:
(ch / a) - (d / f) - (a + b) = -50.18490561773532
先别急着看结果,在程序运行之前可先思考一下,这个复杂的表达式(ch / a)- (d / f) - (b + a)最后的输出类型是什么?它又是如何将不同的数据类型转换成相同的呢?
可以参考图2-9的分析过程。
图2-9 数据类型的转换过程
2.2.11 流程控制语句
到目前为止,所编写的程序,都是简单的程序语句。如果想处理重复的工作时,“循环”就是一个很好的选择,它可以运行相同的程序片段,还可以使程序结构化。在本节中就要认识选择与循环结构语句,学习如何利用这些不同的结构编写出有趣的程序,让程序的编写更灵活,操控更方便。
2.2.11.1 程序的结构设计
一般来说程序的结构包含有下面三种:
1、顺序结构
2、选择结构
3、循环结构
这三种不同的结构有一个共同点,就是它们都只有一个入口,也只有一个出口。程序中使用了上面这些结构到底有什么好处呢?这些单一入、出口可以让程序易读、好维护,也可以减少调试的时间。现在以流程图的方式来让大家了解这三种结构的不同。
2.2.11.1.1 顺序结构
前面所讲的那些例子采用的都是顺序结构,程序至上而下逐行执行,一条语句执行完之后继续执行下一条语句,一直到程序的末尾。这种结构如图2-10所示:
图2-10 顺序结构的基本流程
顺序结构在程序设计中是最常使用到的结构,在程序中扮演了非常重要的角色,因为大部分的程序基本上都是依照这种由上而下的流程来设计。
2.2.11.1.2 选择结构
选择结构是根据条件的成立与否,再决定要执行哪些语句的结构,其流程图如图2-11所示。
图2-11 选择结构的基本流程
这种结构可以依据判断条件的结构,来决定要执行的语句。当判断条件的值为真时,就运行“语句1”;当判断条件的值为假,则执行“语句2”。不论执行哪一个语句,最后都会再回到“语句3”继续执行。举例来说,想在下面的程序中声明两个整数a及b,并赋其初值,如果a大于b,在显示器中输出a-b的计算结果。无论a是否大于b,最后均输出a*b的值。
范例:TestJava2_25.java
//下面的程序说明了if语句的操作,只有当条件满足时才会被执行 public class TestJava2_25 { public static void main(String[] args) { int a = 6, b = 5; System.out.println("a = " + a + " , b = " + b); if (a > b) { System.out.println("a - b = " + (a - b)); } System.out.println("a * b = " + (a * b)); } }
输出结果:
a = 6 , b = 5
a - b = 1
a * b = 30
可以试着更改程序第6行中变量a、b的初值,将a的值设置得比b值小,可较容易观察程序运行的流程。如果输入的a值小于或等于b值,则会跳至执行第10行。
2.2.11.1.3 循环结构
循环结构则是根据判断条件的成立与否,决定程序段落的执行次数,而这个程序段落就称为循环主体。循环结构的流程图如下图2-12所示。
图2-12 循环结构的基本流程
2.2.11.2 选择结构
选择结构包括if、if..else及switch语句,语句中加上了选择结构之后,就像是十字路口,根据不同的选择,程序的运行会有不同的结果。现在先来看看if语句。
2.2.11.2.1 if 语句
在前面简单地介绍了if的用法。要根据判断的结构来执行不同的语句时,使用if 语句就是一个很好的选择,它会准确地检测判断条件成立与否,再决定是否要执行后面的语句。
if语句的格式如下所示:
if (判断条件)
{
//语句1;
//语句2;
//…
//语句n;
}
若是在if语句主体中要处理的语句只有1个,可省略左、右大括号。当判断条件的值不为假时,就会逐一执行大括号里面所包含的语句,if语句的流程图如图2-13所示。
图2-13 if语句的流程图
选择结构中除了if语句之外,还有if…else语句。在if语句中如果判断条件成立,即可执行语句主体内的语句,但若要在判断条件不成立时可以执行其他的语句,使用if…else语句就可以节省判断的时间。
2.2.11.2.2 if…else 语句
当程序中存在含有分支的判断语句时,就可以用if...else语句处理。当判断条件成立,即执行if语句主体;判断条件不成立时,则会执行else后面的语句主体。
if…else语句的格式如下:
if (判断条件)
{
//语句主体1;
}
else
{
//语句主体2;
}
若是在if语句或else语句主体中要处理的语句只有一个,可以将左、右大括号去除。if…else语句的流程图如图2-14所示。
图2-14 if..else语句的基本流程
下面举一个简单的例子:声明一个整型变量a,并给其赋初值5,在程序中判断a是奇数还是偶数,再将判断的结果输出。
范例:TestJava2_26.java
//以下程序说明了if...else的使用方法 public class TestJava2_26 { public static void main(String[] args) { int a = 5; if (a % 2 == 1) { System.out.println(a + " 是奇数!"); } else { System.out.println(a + " 是偶数!"); } } }
输出结果:
5 是奇数!
程序说明:
1、第7~10行为if…else语句。在第7行中,if的判断条件为a%2 == 1,当a除以2取余数,若得到的结果为1,表示a为奇数,若a除以2取余数得到的结果为0,则a为偶数。
2、当a除以2取余数的结果为1时,即执行第8行的语句,输出“a为奇数!”;否则执行第10行,输出“a为偶数!”。
3、可以自行将变量a的初值更改,再重复执行程序。
从上面的程序中发现,程序的缩进在这种选择结构中起着非常重要的作用,它可以使设计者编写的程序结构层次清晰,在维护上也就比较简单。所以在编写程序时要养成缩进的好习惯。
有一种运算符可以代替if…else语句,即前面介绍的条件运算符,使用条件运算符时,操作数有3个(三目运算符),其格式如下:
条件判断 ? 表达式1 : 表达式2
将上面的格式以if语句解释,就是当条件成立时执行表达式1,否则执行表达式2,通常会将这两个表达式之一的运算结果指定给某个变量,也就相当于下面的if…else语句:
if (条件判断)
变量x = 表达式1;
else
变量x = 表达式2;
可以发现,使用条件运算符编写程序时用一个语句就可以替代一长串的if…else语句。
2.2.11.2.3 if...else if…else 语句
如果需要在if…else里判断多个条件时,就需要if...else if … else语句了,其格式如下:
if (条件判断1)
{
//语句主体1;
}
else if (条件判断2)
{
//语句主体2;
}
… // 多个else if()语句
else
{
//语句主体n;
}
这种方式用在含有多个判断条件的程序中,请看下面的范例:
范例:TestJava2_27.java
//以下程序说明了多分支条件语句if…else if ...else的使用 import java.util.*;//使用Scanner需要引入的包 public class TestJava2_27 { public static void main(String[] args) { System.out.print("请输入您的成绩:"); int iScore = 0; Scanner scan = new Scanner(System.in);//从键盘录入数据 iScore = scan.nextInt(); if (iScore < 0 || iScore > 100) { System.out.println("您输入的分数不正确!"); return; } if (iScore >= 90 && iScore <= 100) { System.out.println("你得了A~"); } else if (iScore >= 80) { System.out.println("你得了B~"); } else if (iScore >= 70) { System.out.println("你得了C~"); } else if (iScore >= 60) { System.out.println("你得了D~"); } else { System.out.println("你还是准备补考吧~"); } } }
可以看出if…else if…else比单纯的if...else语句可以含有更多的条件判断语句,可是如果有很多条件都要判断的话,这样写会不会是一件很头疼的事情,下面介绍多重选择语句就可以解决这一件头疼的问题。
2.2.11.3 多重选择语句——switch 语句
switch语句可以将多选一的情况简化,而使程序简洁易懂,在本节中,将要介绍如何使用switch语句以及它的好伙伴——break语句;此外,也要讨论在switch语句中如果不使用break语句会出现的问题。首先,先来了解switch语句该如何使用。
要在许多的选择条件中找到并执行其中一个符合判断条件的语句时,除了可以使用if...else不断地判断之外,也可以使用另一种更方便的方式即多重选择——switch语句。使用嵌套if...else语句最常发生的状况,就是容易将if与else配对混淆而造成阅读及运行上的错误。使用swtich语句则可以避免这种错误的发生。switch语句的格式如下:
switch (表达式)
{
case 选择值1:
语句主体1;
break;
case 选择值2:
语句主体2;
break;
…
case 选择值n:
语句主体n;
break;
default:
语句主体;
}
要特别注意的是,表达式只能是以下几种类型:int、short、byte、char、枚举值。在case语句里的选择值只能是字符常量或整型常量。接下来看看switch语句执行的流程:
1、switch语句先计算括号中表达式的结果。
2、根据表达式的值检测是否符合执行case后面的选择值,若是所有case的选择值皆不符合,则执行default所包含的语句,执行完毕即离开switch语句。
3、如果某个case的选择值符合表达式的结果,就会执行该case所包含的语句,一直遇到break语句后才离开switch语句。
4、若是没有在case语句结尾处加上break语句,则会一直执行到switch语句的尾端才会离开switch语句。break语句在下面的章节中会介绍到,只要先记住break是跳出语句就可以了。
5、若是没有定义default该执行的语句,则什么也不会执行,直接离开switch语句。
根据上面的描述,可以绘制出如图2-15所示的switch语句流程图:
图2-15 switch语句的基本流程
下面的程序是一个简单的赋值表达式,利用switch语句处理此表达式中的运算符,再输出运算后的结果。
范例:TestJava2_28.java
//以下程序说明了多分支条件语句的使用 import java.util.*; public class TestJava2_28 { public static void main(String[] args) { System.out.print("请输入您的成绩:"); int iScore = 0; Scanner scan = new Scanner(System.in); iScore = scan.nextInt(); if (iScore < 0 || iScore > 100) { System.out.println("您输入的分数不正确!"); return; } switch (iScore / 10) { case 10: case 9: System.out.println("你得了A~"); break; case 8: System.out.println("你得了B~"); break; case 7: System.out.println("你得了C~"); break; case 6: System.out.println("你得了D~"); break; default: System.out.println("你还是准备补考吧~"); } } }
程序说明:
该程序实现跟前面嵌套if...else语句相同的功能。可以试试将上面的break去掉会是什么样的输出结果。
感谢阅读。如果感觉此章对您有帮助,却又不想白瞟