2.5 程序基本结构
Java语言和其他结构化编程语言一样,都支持顺序、分支、循环这3种程序控制结构。这3种结构的逻辑执行流程如图2.1所示。
图2.1 3种程序控制结构流程示意图
顺序控制结构:程序中最简单的流程控制方式,按照代码定义的先后顺序,依次一行一行地执行,程序中大多数代码都是按照这种方式组织运行的。在如图2.1所示的顺序控制结构流程中,逻辑过程A、B、C将会被顺序执行。
分支控制结构:代码的执行要根据具体逻辑进行判断,这时代码的运行就会产生由于判断的真假,而产生执行的分支。在如图2.1所示的分支控制结构流程中,当逻辑判断为真时,逻辑过程A将被执行,而当逻辑判断为假时,逻辑过程B将被执行。
循环控制结构:该结构可以按照一定的循环条件来控制相同的逻辑重复运行多次,而不会造成代码的重复。在如图2.1所示的循环控制结构流程中,当循环条件满足时,逻辑过程A将被执行,A被执行后将继续判断循环条件是否满足,如果还满足,A将被重复执行,依此循环直至判断循环条件为假时,循环逻辑控制结束,A将不再被执行。
2.5.1 分支语句
分支语句也被称做条件选择语句,它提供了一种控制机制,使得程序可以根据相应的条件去执行对应的语句。
Java中的分支语句有两种:一种是实现两路分支选择的if…else语句,另一种是实现多路分支选择的switch语句。其中if…else语句根据其应用的复杂程度又可以分为简单if语句和嵌套if语句。
1.简单if语句
简单if条件语句是在满足判断条件后执行相关定义的代码,不满足则不执行任何代码,其语法格式如下:
if(判断条件) { 代码块; }
其中,判断条件为关系或者逻辑运算表达式,其结果必须是布尔类型。代码块是当判断条件的结果为true时要执行的代码,可以是一行,也可以是多行。代码块使用“{}”将执行体代码包含起来,如果执行代码仅是一行,则“{}”可以省略。
【实例2-2】简单if条件语句的使用。
01 class SimpleIfExample{ 02 public static void main(String[] args) { 03 int i=9; 04 System.out.println("i=" + i); //打印输出i的值 05 if (i% 2==0) { //如果i%2的结果等于0,输出相关提示信息 06 System.out.println("i能被2整除"); 07 } 08 if (i %3==0) //如果i%3的结果等于0,输出相关提示信息 09 { 10 System.out.println("i能被3整除!"); 11 } 12 if (i%5==0); //如果i%5的结果等于0,不做任何操作,“;”表示if代码块的结束 13 System.out.println("i能被5整除!"); //该语句将总执行与if条件判断无关 14 } 15 }
【代码说明】在实例2-2定义的类中,第13行的语句将被执行,这显然是错误的,原因就是由第12行的代码“if (i%5==0);”中的分号造成的,将其删除则程序的输出结果将不再打印“i能被5整除!”。
说明
包含判断条件的“()”后特别容易习惯性地添加“;”,这样会造成无论判断结果如何后面的代码块都会执行。
2.If…else语句
If…else条件语句是在满足判断条件时执行相关定义的代码,而不满足条件则执行另外的定义的代码,其语法格式如下:
if(判断条件){ 代码块1 } else{ 代码块2 }
其与简单if语句的不同之处在于,使用else关键字来执行判断条件结果为false时代码块2中的代码,这些代码可以是一行,也可以是多行代码。
【实例2-3】if…esle条件语句的使用。
01 class IfExample { 02 public static void main(String[] args) { 03 int i=9; 04 System.out.println("i=" + i); //打印输出i的值 05 if (i%2==0) { 06 System.out.println("i能被2整除");//如果i%2的结果等于0,输出相关提示信息 07 } else { //如果i%2的结果不等于0,输出相关提示信息 08 System.out.println("i不能被2整除"); 09 } 10 if (i%3==0) { //如果i%3的结果等于0,输出相关提示信息 11 System.out.println("i能被3整除!"); 12 } else { //如果i%3的结果不等于0,输出相关提示信息 13 System.out.println("i不能被3整除!") 14 } 15 if (i%5==0) //如果i%5的结果等于0,输出相关提示信息 16 System.out.println("i能被5整除!"); 17 else //如果i%5的结果不等于0,输出相关提示信息 18 System.out.println("i不能被5整除!"); 19 } 20 }
【代码说明】在实例2-3定义的类中,第5~9行使用了if…else条件语句,根据变量i能否整除2来决定输出的内容。第10~14行及第15~19行也使用了同样的if…else条件语句。
3.多层嵌套if语句
在if语句中执行的代码块可以是任何合法的Java语句,当然可以是if语句本身,这样就构成if语句的嵌套结构,从而形成多分支选择。多层嵌套的if语句的执行逻辑流程如图2.2所示。
图2.2 多层嵌套if语句结构流程示意图
if语句既可以嵌套在if代码块中,也可以嵌套在else代码块中,常见的多层嵌套if语句的语法格式如下:
if (判断条件1){ 代码块1 } else if(判断条件2){ 代码块2 } … else if(判断条件n) { 代码块n; } else { 代码块n+1; }
【实例2-4】多层嵌套if语句的使用。
01 class ComIfExample { 02 public static void main(String[] args) { 03 int i=9; 04 System.out.println("i=" + i); //打印输出i的值 05 if (i %2==0) { //如果i%2的结果等于0,输出相关提示信息 06 System.out.println("i能被2整除"); 07 } else if (i%3==0) { //如果i%3的结果等于0,输出相关提示信息 08 System.out.println("i能被3整除!"); 09 } else if (i%5==0){ //如果i%5的结果等于0,输出相关提示信息 10 System.out.println("i能被5整除!"); 11 }else{ //都不能被整除时,输出相关提示信息 12 System.out.println("i不能被2、3、5整除!"); 13 } 14 } 15 }
【代码说明】在实例2-4定义的类中,第5~14行的多层嵌套if语句实现了实例2-3定义的类中由3个if…else条件语句完成的功能。
需要注意的是,在多层嵌套if语句中,else总是与离它最近的if匹配。例如下述示例代码:
if(x>0) if(y>0) z=100; else z=99;
此处的else与if(y>0)相配,也就是说,当y<=0时,z的值为99。
将上述代码修改如下:
if(x>0){ if(y>0) z=100; } else z=99;
此处的else与if(x>0)相配,也就是说,当x<=0时,z的值为99。
4.switch多分支语句
在if语句中,判断语句的结果只能有两种:true或false。若情况更多时,就需要使用多层嵌套if语句,这样书写起来比较麻烦,使得程序的可读性差,并且容易产生错误。这种情况下,使用另一种可提供更多选择的switch多分支语句实现起来就比较方便。switch语句的语法格式如下:
switch(判断表达式){ case value1: 语句块1; break; case value2: 语句块2; break; …… case valueN: 语句块N; break; default: 语句块N+1; }
使用switch语句必须注意如下问题。
❑ switch表达式的返回值类型必须为byte、short、int、long或char类型。
❑ case后的值value必须是与switch表达式类型兼容的特定的一个常值(它必须为一个常值,而不是变量),每个值必须不同,重复的case值是不允许的。
❑ switch表达式的值按照顺序与每个case语句中的常量比较,如果有一个常量value i与表达式的值相等,则执行该case语句后的语句块i。如果没有一个常量与表达式相同,则执行default语句,default语句是可选的,如果没有default语句,则程序不作任何操作,直接跳出switch语句。
❑ break语句用来在执行完一个case分支后,使程序跳出switch语句,即终止switch语句的执行。
【实例2-5】switch语句的使用。
01 public class Month{ 02 public static void main(String args[]){ 03 int month; 04 int year=2009; 05 int numDays=0; 06 //通过main()方法进行参数传递 07 month=Integer.parseInt(args[0]); 08 //使用switch语句进行多分支判断 09 switch(month){ 10 case 1: 11 case 3: 12 case 5: 13 case 7: 14 case 8: 15 case 10: 16 case 12: 17 numDays=31; 18 break; //break跳出switch语句 19 case 4: 20 case 6: 21 case 9: 22 case 11: 23 numDays=30; 24 break; //break跳出switch语句 25 case 2: 26 //判断此年份是不是闰年 27 if(((year%4==0)&&!(year%100==0))||(year%400==0)) 28 numDays=29; 29 else 30 numDays=28; 31 break; //break跳出switch语句 32 }
【代码说明】在实例2-5定义的类中实现了根据输入的月份显示该月有多少天的功能,第9行中设置了switch语句的判断表达式,从第10~16行的case语句当满足条件时都将执行第17行的语句,执行完成后通过第18行的break语句跳出switch语句。
2.5.2 循环语句
循环语句的作用是在一定条件下,反复执行一段程序代码,直到满足终止条件为止。Java语句提供的循环语句有:while语句、do…while语句、for语句。当然循环语句也是可以多重嵌套使用的。
1.while语句
while语句是Java中最经常使用的循环控制语句之一,其一般是按照某个条件的判断来进行循环,当然也可以使用循环变量控制循环的次数,能够比较方便地实现不固定次数的循环操作,其语法格式如下:
while(循环条件) { 循环主体 }
while语句会首先执行循环条件,循环条件为true时才执行循环体内定义的循环主体的逻辑语句。循环条件会在循环主体的语句执行完毕后再次执行,如果结果还为true,则将继续循环,直至结果为false,这时while循环就将结束。
【实例2-6】while循环语句的使用。
01 class WhileExample { 02 public static void main(String[] args) { 03 int a=10; 04 int b=20; 05 while(a>b) //由于a>b第一次结果就为false,所以该循环体一次都不被执行 06 { 07 System.out.println("a="+a+" b="+b+" a>b"); //打印相关的提示信息 08 a--; //a递减 09 } 10 while(a<b)//a<b的计算结果为true,该循环体将一直被执行,直至a<b的运算结果为false 11 { 12 System.out.println("a="+a+" b="+b+" a<b"); //打印相关的提示信息 13 a++; //a递增 14 } 15 } 16 }
【代码说明】在实例2-6定义的类的第5~9行使用了while循环语句,根据第5行中的循环条件表达式的值来决定是否执行循环体中的语句。第10~14行也使用了同样的while循环语句。
2.Do…while语句
Do…while语句也是按照循环条件来进行循环,与while语句非常类似,唯一的区别是循环条件和循环主体执行语句的前后顺序有所不同。While语句是先检查循环条件是否成立后再执行循环主体语句,而do…while是先执行循环主体语句后再检查循环条件。因此,不管循环条件是否满足,do…while循环至少执行一次。其语法格式如下:
do { 循环主体 } while(循环条件);
注意
while(循环条件)后面的分号不能丢掉,这是初学者经常容易遗漏的地方。
【实例2-7】do…while循环语句的使用。
01 class DoWhileExample { 02 public static void main(String[] args) { 03 int a=10; 04 int b=20; 05 do{ //会先被执行一次,虽然不符合while条件 06 System.out.println("a="+a+" b="+b+" a>b"); 07 a--; //a被自减a=9 08 }while(a>b); 09 System.out.println(); //输出空行 10 do 11 { 12 System.out.println("a="+a+" b="+b+" a<b"); //第一次被执行时a=9; 13 a++; 14 }while(a<b); 15 } 16 }
【代码说明】在实例2-7定义的类的第5~8行使用了do…while语句,该语句将首先执行一次循环体然后再进行循环条件的检查。第10~14行也使用了同样的do…while循环语句。
3.for语句
for语句是Java中最经常使用的循环控制语句,for循环语句一般和控制循环次数的循环变量结合使用,能够比较方便地实现固定次数的循环操作。其语法格式如下:
for(控制变量初始值;继续条件;控制变量调整值 ){ //循环主体 }
其中,控制变量初始值用于设置循环开始和结束的变量的初始值,只是在程序开始的时候执行一次。继续条件是一个布尔表达式,作为判断循环是否继续的条件,如果布尔值为真,就执行一次循环体,否则退出循环。控制变量调整值用于改变循环控制变量的值。
【实例2-8】for循环语句的使用。
01 public class Sum{ 02 public static void main(String args[]){ 03 int i,sum=0; 04 //使用for语句循环100次,进行加法运算 05 for(i=1;i<=100;i++){ 06 sum+=i; 07 } 08 System.out.println("sum="+sum); 09 } 10 }
【代码说明】在实例2-8定义的类中实现了求1+2+3+…+100的和的功能,第5~7行使用了for循环,循环100次进行加法的累加运算。
2.5.3 跳转语句
Java中的跳转语句包括break和continue,这些跳转语句经常与分支和循环语句结合使用,从而实现相关的流程控制。
1.break跳转语句
break跳转语句的作用就是跳出指定的语句块,并从紧跟该块的第一条语句处执行。例如终止switch语句的执行和跳出循环等。在之前的switch多分支语句中已经介绍过break在其中的用法了,下面着重介绍break在循环语句中的使用。
【实例2-9】break语句在循环语句中的使用。
01 public class BreakExample { 02 public static void main(String[] args) { 03 for (int i=0; i<=10; i++) { 04 if (i==5) { 05 //当i等于5时,跳出for循环 06 break; 07 } 08 System.out.print(i + "\t"); 09 } 10 } 11 }
【代码说明】在实例2-9定义的类中的for循环正常执行应该是输出0到10的整数,但是在第4~7行添加了一个循环变量等于5就使用break语句中止循环的逻辑代码,所以程序运行结果是输出0到4的整数。
2.continue跳转语句
continue语句只能使用在循环语句内部,其功能是跳过该次循环的尚未执行的代码,继续执行下一次循环逻辑。它与break语句的最大区别就是,break语句将跳出整个循环,而continue语句只是跳出本次循环。
【实例2-10】continue语句在循环语句中的使用。
01 public class ContinueExample { 02 public static void main(String[] args) { 03 for (int i=0; i<=10; i++) { 04 if (i==5) { 05 //当i等于5时,跳出当前这一次循环 06 continue; 07 } 08 System.out.print(i + "\t"); 09 } 10 } 11 }
【代码说明】实例2-10将实例2-9中的break换成了continue,则程序的执行结果将大不相同。因为第6行的continue语句只是跳出本次循环,因此,当循环变量等于5时,使用continue语句中止当前本次循环,所以程序运行结果是输出0~10中除了5以外的整数。