【Java 专题补充】流程控制语句
流程控制语句是用来控制程序中各语句执行顺序的语句,是程序中既基本又非常关键的部分。流程控制语句可以把单个的语句组合成有意义的、能完成一定功能的小逻辑模块。最主要的流程控制方式是结构化程序设计中规定的三种基本流程结构。
1.1 结构化程序设计的三种基本流程
任何程序都可以且只能由三种基本流程结构构成,即顺序结构、分支结构和循环结构。
顺序结构是三种结构中最简单的一种,即语句按照书写的顺序依次执行。分支结构又称为选择结构,它根据计算所得的表达式的值来判断应选择执行哪一个流程的分支。循环结构则是在一定条件下反复执行一段语句的流程结构。这三种结构构成了程序局部模块的基本框架,如图 3-2 所示。
Java语言虽然是面向对象的语言,但是在局部的语句块内部,仍然需要借助于结构化程序设计的基本流程结构来组织语句,完成相应的逻辑功能。Java的语句块是由一对大括号括起的若干语句的集合。Java中,有专门负责实现分支结构的条件分支语句和负责实现循环结构的循环语句。
1.2 简单语句
最简单的流程是顺序结构,在Java中一句一句地书写。而最简单的语句是方法调用语句及赋值语句,是在方法调用或赋值表达式后加一个分号(;),分别表示完成相关的任务及赋值。如:
System.out.println("Hello World");
a = 3 + x;
b = a > 0 ? a : -a;
s = TextBoxl.getText();
d = Integer.parseInt(s);
1.3 分支语句
1. if语句
if语句的一般形式是
if(条件表达式)
语句块; //分支
else
语句块; //else 分支
其中,语句块是一条语句(带分号)或者是用一对花括号括起来的多条语句;条件表达式用来选择判断程序的流程走向,在程序的实际执行过程中,如果条件表达式的取值为真,则执行i分支的语句块,否则执行else分支的语句块。在编写程序时,也可以不书写else 分支。此时,若条件表达式的取值为假,则绕过分支直接执行if语句后面的其他语句。语法格式如下:
if(条件表达式)
语句块;
下面是一个i语句的简单例子,实现求某数的绝对值,
if(a>=0)b=a;else b =-a;
具体的例子,即LeapYear.java 判断闰年:【日撸 Java 三百行】Day 4(条件语句实战——闰年问题)-CSDN博客
2. swtich 语句
switch语句是多分支的开关语句,一般形式是:
switch(表达式) {
case判断值1:一系列语句1:break:
case判断值2:一系列语句2:break;...
case 判断值n:一系列语句n;break;
default:一系列语句 n+1}
注意:
其中,表达式必须是整数型或字符类型,从Java6开始,表达式可以是字符串(String)类型或者枚举类型。判断值必须是常数,而不能是变量或表达式。
switch语句在执行时,首先计算表达式的值,这个值必须是整型、字符型、字符串或枚举类型,同时应与各个case分支的判断值的类型相一致。计算出表达式的值之后,将它先与第一个case 分支的判断值相比较,若相同,则程序的流程转入第一个case 分支的语句块;否则,再将表达式的值与第二个case分支相比较,……依次类推。如果表达式的值与任何一个 case 分支都不相同,则转而执行最后的 default 分支;在 default 分支不存在的情况下则跳出整个 switch 语句。
注意:
switch语句的每一个 case 判断,在一般情况下都有 break 语句,以指明这个分支执行完成后,就跳出该switch语句。在某些特定的场合下可能不需要 break 语句,如在若干判断值共享同一个分支时,就可以实现由不同的判断语句流入相同的分支。
具体的例子,即 scoreToLevel.java 根据考试成绩判断对应等级:【日撸 Java 三百行】Day 5(Switch语句)-CSDN博客
1.4 循环语句
循环结构是在一定条件下反复执行某段程序的流程结构,被反复执行的程序被称为循环体。循环结构是程序中非常重要和基本的一种结构,它是由循环语句来实现的。Java的循环语句共有三种:for、while和do…while 语句,如图3-4 所示。
三种语句在使用时,都要表达以下几个要素。
- 循环的初始化。
- 循环的条件。
- 循环体。
- 循环的改变
下面的例题是用三种方式来表达的1+2+3+…+100的循环相加的过程。
例:Sum100.java 循环语句用于求 1=2+3+...+100
publie class Sum100 {public static void main(String args[]) {int sum, n;System.out.println("\n**** for statement ****");sum = 0:for(int i = 1; i <= 100; i++) { //初始化,循环条件,循环改变sum += i; //循环体}System.out.println("sum is "+ sum);System.out.println("\n**** while statement ****");sum = 0;n = 100; //初始化while(n > 0) { //循环条件sum += n; //循环体n--; //循环改变}System.out.println("sum is " + sum);System.out.println("\n**** do_while statement ****");sum = 0;n = 1; //初始化do {sum += n; //循环体n++; //循环改变} while( n<= 100); //循环条件System.out.println("sum is "+ sum);}
}
运行结果如下:
可以从中比较这三种循环语句,从而在不同的场合选择合适的语句。
下面比较详细地讲解这三种循环语句的用法。
1. for 语句
for语句是Java语言三个循环语句中功能较强、使用较广泛的一个,它的流程结构可参看图3-4(a)。for语句的一般语法格式如下:
for(表达式1;表达式2;表达式 3)
循环体
其中,表达式1完成初始化循环变量和其他变量的工作:表达式2是返回布尔值的条件表达式,用来判断循环是否继续;表达式3用来修改循环变量,改变循环条件。3个表达式之间用分号隔开。
for语句的执行过程是首先计算表达式1,完成必要的初始化工作;再判断表达式2的值,若为真,则执行循环体,执行完循环体后再返回表达式3,计算并修改循环条件。这样一轮循环就结束了。第二轮循环从计算并判断表达式2开始,若表达式的值仍为真,则继续循环:否则,跳出整个for语句执行下面的句子。for语句的三个表达式都可以为空,但若表达式2也为空,则表示当前循环是一个无限循环,需要在循环体中书写另外的跳转语句终止循环。
注意:
for 循环的第1个表达式中,可以定义变量,这里定义的变量只在该循环体内有效。如for(int n = 0; n < 100; n++) {System.out.println(n); }
2. while 语句
while语句的一般语法格式如下:
while(条件表达式)
循环体
其中,条件表达式的返回值为布尔型,循环体可以是单个语句,也可以是复合语句块。
while语句的执行过程是先判断条件表达式的值,若为真,则执行循环体,循环体执行完之后再无条件转向条件表达式做计算与判断:当计算出条件表达式为假时,跳过循环体执行 while 语句后面的语句。
3. do...while句
do...while语句的一般语法结构如下:
do
循环体
while(条件表达式);
do...while语句的使用与while语句很类似,不同的是,它不像while语句是先计算条件表达式的值,而是无条件地先执行一遍循环体,再来判断条件表达式。若表达式的值为真则运行循环体,否则跳出 do...while循环,执行下面的语句。可以看出,do...while 语句的特点是它的循环体将至少被执行一次。
4. 加强的 for 语句
另外在Java5 引入了一种主要用于数组的增强型 for 循环。
格式如下:
for(声明语句 : 表达式)
{//代码句子
}
这种增强就如同当年C++的C++11扩充一样,无论是使用方法上还是效果上都是类似的。
声明语句:声明新的局部变量,该变量的类型必须和数组元素的类型匹配(即与表达式中的数据结构集合中的每个子项的类型匹配)。其作用域限定在循环语句块,其值与此时数组元素的值相等。
表达式:表达式是要访问的数组名,或者是返回值为数组的方法。
口说无凭,计算机人还是要以“show me the code !”才行
public class Test {public static void main(String[] args) {int[] numbers = { 10, 20, 30, 40, 50 }; // Create a int arrayfor (int x : numbers) { // Get the elements in the array in orderSystem.out.print(x);System.out.print(",");}System.out.print("\n");String[] names = { "James", "Larry", "Tom", "Lacy" }; // Create a string arrayfor (String name : names) {System.out.print(name);System.out.print(",");}}
}
另外通过实际测试,发现了java5的这种增强for与C++11的增强for一个相同点与差异点:
1.相同:for(val : array)的遍历之下的每个val值是仅仅可读的,但是不可写,val只能用来获取而无法通过修改val来修改array对于中的数据。用计算机的话来说,读取的val不是这个array中那个对应数的地址,因此修改val无法改动到array。这个C++与java一致。
2.不同:C++可以利用关键符“&”,用for(&val : array)的形式直接读取array对于元素的地址,这样可以直接修改array中对应的值,而这点java目前我还没有查到可以做到的方法(若有欢迎指正!)
可见相比于一般的for循环,这个方法能更快实现我们的遍历任务,避免我们对于一个未知长度的数组还要进行获取长度并再用循环因子进行索引遍历的麻烦。 但是也得辩证看待这个问题,对于某些需要用遍历因子完成的算法,基本的for又会简单一些,所以不要图简单就一味使用,要针对具体问题具体分析。
1.5 跳转语句
跳转语句用来实现程序执行过程中流程的转移。前面,在switch语句中使用过的break语句就是一种跳转语句。为了提高程序的可靠性和可读性,Java语言不支持无条件跳转的goto语句。Java的跳转语句有三个:continue、break和return语。
1. continue 语句
continue 语句必须用于循环结构中,它有两种使用形式。
一种是不代标号的continue语句,它的作用是终止当前这一轮的循环,跳过本轮剩余的语句,直接进入当前循环的下一轮。在 while或 do...while循环中,不带标号的 continue 语句会使流程直接跳转至条件表达式。在for循环中,不带标号的continue语句会跳转至表达式3.计算修改循环变量后再判断循环条件。
另一种是带标号的continue语句,其格式是:
continue标号名;
这个标号名应该定义在程序中外层循环语句的前面,用来标志这个循环结构。标号的命名应该符合Java标识符的规定。带标号的continue语句使程序的流程直接转入标号标明的循环层次。
2. break语句
break语句的作用是使程序的流程从一个语句块内部跳转出来,如从switch语句的分支中跳出,或从循环体内部跳出。break语句同样分为带标号和不带标号两种形式。带标号的break语句的使用格式是:
break标号名;
这个标号应该标志某一个语句块。执行break语句就从这个语句块中跳出来,流程进入该语句块后面的语句。
不带标号的 break语句从它所在的 switch 分支或最内层的循环体中跳转出来,执行分支或循环体后面的语句。
例:MaxDiv.java 求一个数的最大真约数。程序中从大向小进行循环,直到能整除,则用 break 退出循环。
public class MaxDiv {public static void main(String[] args) {int a = 99;int i = a-1;while(i>0) {if(a % i == 0)break;i--;}System.out.println(a + "的最大真约数为:" + i);}
}
运行结果如下:
3. return 语句
return 语句的一般格式是:
return表达式:
return 语句用来使程序流程从方法调用中返回,表达式的值就是调用方法的返回值。如果方法没有返回值,则retum语句不用表达式。
例:Prime100Continue.java求100~200 间的所有质数。
public class Prime100Continue {public static void main(String args[]) {System.out.println("**** 00--200的质数 ****");int n = 0;outer: for(int i = 101; i <= 200; i += 2) { //外层循环for(int j = 2; j < i; j++) //内层循环if(i % j == 0) //不是质数,则继续外层循环continue outer;}System.out.print(" " +i); //显示质数n++; //计算个数if(n < 10) //未满10个数,则不换行continue;System.out.println( );n = 0;}System.out.println( );}
}
该例通过一个嵌套的for语句来实现。其中,外层循环遍历101~200,内层循环针对一个数i,用2到i-1之间的数去除,若能除尽,则表明不是质数,直接继续外层的下一次循环(continue outer)。这里 outer 是语句的“标签”,表明是哪个循环,可以改成其他任意标识符,只要与continue后用的标识符一致即可。程序运行结果如下: