1、第4章 流程控制,本章要点:条件语句循环语句分支语句中断与继续,4.1 编程风格,缩排缩排又称缩进或跳格。缩排是影响代码视觉效果的重要因素之一。大多数程序员都喜欢用键盘上的【Tab】键来完成这项工作,也有的程序员喜欢用空格键来完成缩排。【Tab】和空格键各有各的好处:用【Tab】键快捷方便,但在跳格长度设置不同的编辑器中,所表现的缩排效果不一样,甚至会发生缩排混乱;用空格键来缩排,格式是固定不变的,可以写出定型的代码,但是需要大量重复地按键,降低了编码速度。一般使用【Tab】键,跳格长度设为4格,这样程序的视觉效果很不错而且键入速度也快。至于在不同编辑器中,建议统一【Tab】键跳格长度即可。U
2、ltraEdit提供了【Tab】和空格键相互替换的功能,这样虽然用的是【Tab】键,但缩排的实现是用空格来代替的。,在以下几种情况下就需要使用缩排。当程序需要有层次感时,例如: void run(int i) while(i0)sleep(1000);i-; 当集中定义变量的时候,如: int i; Date tomorrow; String str; 当函数参数过多的时候,如: Window.open (“test.htm“,“NewWin“,“status=yes,height=200,width=200“ );,空格合理地使用空格可以使程序看起来更清爽,一般在以下地方使用。赋值语句和表达
3、式等,如:if(a b) i+)/这样看起来很挤分隔参数等,如:new Calendar(2003, 11, 23, 23, 12, 59)等需要清晰明了的地方。,空行适当的空行,可以使模块结构更明显。一般有这么几种情形:完成某个相对独立的操作的代码可以聚在一块儿,前后以空行隔开;功能相似的代码可以聚在一块儿,前后以空行隔开;形式相似的代码可以聚在一块儿,前后以空行隔开;方法与方法之间隔空行等等。下面是实际项目中的一段代码,读者可以从中领会一下空行的使用技巧。,命名命名规则的问题更是难以统一,这里只能提醒读者注意几个原则上的问题。前后一致,这一点是非常重要的,比如有两个方法,一个命名为getN
4、ame(),而另一个命名为getStudentSex(),这会给人一种错觉:这两个方法不属于同一类,虽然功能上它们是相对应的。尽量做到望文生义,如果用name或studentName来描述学生的姓名就比较直观。 注释对于类及方法的注释,一般情况下都要有对于变量的注释,要根据情况有取有舍。在程序比较难懂的地方,应该有比较详细的注释,程序比较易懂的地方,可以采用少量或不用注释。,4.2 作用域,要想正确地理解控制的作用,必须首先理解作用域的概念。即不同的控制在什么样的范围内起作用,这就是我们所说的作用域。对于作用域中所定义的各种变量,作用域限定了这些变量的可被访问范围,也就是说“变量的可见性”及“
5、存在时间”。所谓变量的可见性是指只有在规定的作用域范围内,变量是可以被访问及操纵控制的。所谓变量的存在时间是指只有在规定作用域范围内,变量是存活的,一旦超出了变量的存活范围,变量就不存在了。对于这种不存在的理解应该有两种情况: (1)内存立即被回收,变量在内存中不存在了,这种情况主要是针对于基本类型。 (2)对象句柄不存在了,对象不再被操纵,对象的内容还存在,这种情况主要针对对象类型。,4.2.1 块作用域一个块或复合语句是用一对花括号(“”)括起来的任意数量的简单Java语句。块定义了变量的作用范围。对于块我们主要理解以下两方面就可以了。,(1)块可以被嵌套 例4-1 程序清单:PartAr
6、ea.java /* 块的嵌套*/ public class PartArea public static void main(String args)/main方法开始int a = 15;int b = 2;if(a = 15)/条件块开始double c = 2;/c是可用的System.out.println(a + “/“ + c + “=“ + (a/c);System.out.println(“the value a is “ + a);/a是可用的/条件块结束/System.out.println(“the value c is “ + c);/在这里c已经不再可用System
7、.out.println(a + “/“ + b + “=“ + (a/b);System.out.println(a + “%“ + b + “=“ + (a%b);/main方法结束 ,(2)嵌套块内不可以声明相同名字的变量 例4-2 程序清单:PartArea1.java /*块的嵌套*/ public class PartArea1 public static void main(String args)/main方法开始int a = 15;int b = 2;if(a = 15)/条件块开始int a = 10;double c = 2;/c是可用的System.out.print
8、ln(a + “/“ + c + “=“ + (a/c);System.out.println(“the value a is “ + a);/a是可用的/条件块结束/System.out.println(“the value c is “ + c);/在这里c已经不再可用System.out.println(a + “/“ + b + “=“ + (a/b);System.out.println(a + “%“ + b + “=“ + (a%b);/main方法结束 ,例4-3 程序清单:PartArea2.java /*块的嵌套*/ public class PartArea2 int a
9、 = 10;public static void main(String args)/main方法开始int a = 15;int b = 2;if(a = 15)/条件块开始double c = 2;/c是可用的System.out.println(a + “/“ + c + “=“ + (a/c);System.out.println(“the value a is “ + a);/a是可用的/条件块结束/System.out.println(“the value c is “ + c);/在这里c已经不再可用System.out.println(a + “/“ + b + “=“ + (
10、a / b);System.out.println(a + “%“ + b + “=“ + (a % b);/main方法结束 ,(1)所谓嵌套块,是方法内的嵌套,不包括类的花括号。 (2)换个角度理解,不允许重复定义的是局部变量,对于成员变量或类变量是可以被重复定义的,局部变量的值覆盖全局变量的值(请读者注意,局部变量的值只是在局部作用域范围内有效,出了局部变量作用域,变量的值还是全局变量的值)。,例4-4 程序清单:PartArea3.java /*块的嵌套*/ public class PartArea3 static int a = 10;public static void main
11、(String args)/main方法开始if(a = 10)/条件块开始int a = 15;System.out.println(“局部变量 a is “ + a);/a的值是15/条件块结束System.out.println(“全局变量 a is “ + a);/在这里a的值10/main方法结束 ,4.2.2 对象的存活时间Java中的对象,只有在存活时间上与主类型(基本类型)不一致,在变量的作用域的其他方面是一致的。下面我们分析一下对象类型的存活时间。提到对象类型,就内容而言,读者还没有接触到,但为了知识点的对比与连续,我们将这部分内容放到这里,主要是为了与主类型变量有个比较,使
12、读者更能理解对象类型变量与主类型变量的不同点,读者可以提前先翻阅一下第7章关于对象及对象句柄的内容,再回来看这一节的内容。,4.3 条件语句,条件语句也称为假设语句,在Java中是利用if这个关键字来实现这种假设的关系的,它的英文原意是“如果”。也就是说,如果,就,否则。下面我们还是用一个生活中的小例子来分析这种假设的构成。例如:如果我中了五百万大奖,我就周游世界,否则,只有老老实实地呆在原地。 if (条件)目的1;else目的2;,4.3.1 if () 这是if语句的最简单的一种表现形式,其表达式为:if(条件)目的;在上面的句法中,需要读者注意的是,if后面的“条件”必须用圆括号括起来
13、,而且“条件”的值必须是布尔型的,如果是“真”,就执行目的,否则,就跳过目的。if(目的不止一个)目的1;目的2;目的3;,例4-5 程序清单:Suppose.java /* *条件语句第一种形式测试 */ public class Suppose public static void main(String args)double mySales = 6000;if( mySales 5000)System.out.println(“请朋友大餐一次“);System.out.println(“再去游泳“);System.out.println(“打电子游戏“); ,if 语句流程图,4.3.
14、2 if () else 这种语句的表现形式也是最常用的,它所表达的意思就是,如果条件满足,就执行if()后面的,如果条件不满足,就执行else后面的内容。,例4-6 程序清单:Suppose2.java /* *条件语句第二种形式测试 */ public class Suppose2 public static void main(String args)double mySales = 4000;if( mySales 5000)System.out.println(“请朋友大餐一次“);System.out.println(“再去游泳“);System.out.println(“打电子游
15、戏“);elseSystem.out.println(“只能吃方便面了“); ,if else 流程图,4.3.3 if else if 这种形式的写法虽然有点陌生,但通过接下来的学习,读者会发觉它实际上就是前面两种形式的结合。if(条件一)目的一;else if (条件二)目的一;,else if (条件三) 目的一; else 不满足任何条件的结果; ,ifelse if结构的流程图,例4-7 程序清单:ConditionTest.java /* *else块的邻近属性 */ public class ConditionTest public static void main(String
16、 args)int salary = 5000;if (salary 5000)System.out.println(“the first condition my salary is: “ + salary);if (salary 4500)System.out.println(“the second condition my salary is: “ + salary);elseSystem.out.println(“the else my salary is: “ + salary); ,4.4 循环语句,4.4.1 不确定循环所谓不确定循环,也就是我们不能确定循环所要执行的次数,执行的
17、次数是根据程序中参数的变化自动控制的。不确定循环主要有while和do/while两种表现形式。1. whilewhile的意思就是“当”,在循环控制中可以这样理解,它的语法格式是:while (条件) 目的一;目的二;,例4-8 程序清单:BuyHouse.java /* *while循环控制结构的测试 */ public class BuyHouse public static void main(String args)final double HOUSEFUND = 200000;double salary = 2000;double fund = 0;int years = 1;wh
18、ile (fund HOUSEFUND)fund += salary*0.05*12;years+;salary = salary *1.1;System.out.println(“the total years is: “ + years);System.out.println(“the total fund is : “ + fund); ,while循环控制流程图,是,循环体开始,fund20万元,更改fund,years+,否,循环体结束,2. do/while 例4-9 程序清单:BuyHouse2.java /* *while循环控制结构的测试 */ public class Bu
19、yHouse2 public static void main(String args)final double HOUSEFUND = 200000;double salary = 2000;double fund = 0;int years = 1;dofund += salary*0.05*12;years+;salary = salary *1.1;while (fund HOUSEFUND);System.out.println(“the total years is: “ + years);System.out.println(“the total fund is : “ + fu
20、nd); ,例4-10 程序清单:DifferTest.java /* *测试不确定循环的两种表现形式的区别 */ public class DifferTest public static void main(String args)int i = 2;doi+;System.out.println(“the value i is: “ + i );while (i 2); ,例4-11 程序清单:DifferTest2.java /* *测试不确定循环的两种表现形式的区别 */ public class DifferTest2 public static void main(String
21、args)int i = 2;while(i 2)i+;System.out.println(“the value i is: “ + i ); ,do/while循环控制结构流程图,4.4.2 确定循环for( )循环是最简单的循环语句,它可以通过计数器或在每次循环后修改某个类似于计数器变量的值来控制它。它的格式如下for(初始化表达式; 判断表达式; 递增(或递减)表达式)执行语句;初始化表达式:用来设定循环控制变量的初始值,也就是循环的起点。判断表达式:用来判断循环是否结束的表达式,也就是循环的终点。程序循环是否持续进行由判断表达式决定;通常判断表达式是关系表达式,当关系表达式的值为真时
22、,程序继续进行循环,当关系表达式的值为假时,循环结束。递增(递减)表达式:是循环控制变量的递增或递减。它又称为循环控制的步长,也就是每次循环,循环变量增长(或减少)的速度。,例4-12 程序清单:Circle.java /* *输出数字到控制台 */ public class Circle public static void main(String args)for( int i = 1; i = 10; i+)System.out.print(“ “ + i); ,for( )循环控制流程图,(1)如果在初始化表达式定义了一个初始化变量,那么该变量的作用域范围是从循环开始到循环结束。例如:
23、for(int i = 1; i = 10; i+)/初始化表达式定义了初始化变量i = 1。/ i 在这里已经不再可用。 (2)如果想在循环体外部使用循环计数器的最终结果,应该在循环开始外就声明。例如:int i = 1; /定义循环计数器变量 i = 1。for(i = 1; i = 10; i+) / i 在这里还可以再用。,(3)在同级别的不同for( )循环中,可以定义相同名字的变量。例如: for(int i = 1; i = 10; i+)/初始化表达式定义了初始化变量i = 1。 /第一个循环块 i 在这里已经消失了。 for(int i = 1; i = 20; i+)/i
24、在这里可以被重新定义。 (4)在被包含的for( )循环块内不可以定义相同名字的变量。例如: for(int i = 1; i = 10; i+)/初始化表达式定义了初始化变量i = 1。 for( int i = 1; i = 20; i+)/ i 是不可以被重新定义,需要声明一个新变量j ,(5)for( )循环与while循环是完全等价的。 for(初始化表达式; 判断表达式; 递增(或递减)表达式) 执行语句; 完全等价于: 初始化表达式;while(判断表达式)执行语句;递增(或递减)表达式; ,1. 逗号运算符逗号运算符不是逗号分隔符。逗号分隔符是用于分隔方法的不同变量。在Java
25、中逗号运算符的唯一使用场所就是for循环,在初始化循环变量表达式或递增(递减)表达式中,我们用一系列逗号分隔不同的语句,这些语句均参与到循环控制中。,例4-13 程序清单:CommaOperator.java /* *逗号运算符 */ public class CommaOperator public static void main(String args)for( int i = 1, j = i + 10; i 5; i+, j = i * 3)System.out.println(“ i = “ + i +“; j = “ + j); ,2. 无限循环无限循环是指没有判断表达式的for
26、循环,当程序进入到循环体内的时候,由于没有判断表达式来结束正常的循环,使得程序进入到无限循环中,也就是我们平常所说的死循环。 例4-14 程序清单:Unlimited.java /* *无限循环控制 */ public class Unlimited public static void main(String args)for(int i = 1; i+)System.out.println(“i = “ + i); ,4.5 中断与继续,4.5.1 中断中断:在Java中用关键字“break”表示。在循环体内,用于强行退出循环,不再执行循环中剩余的部分。 例4-15 程序清单:BreakT
27、est.java /* *中断测试 */ public class BreakTest public static void main(String args)for(int i = 1; i 20; i+)if(i = 10)break;System.out.print(“ “ + i);System.out.println(“n the Reptation is over!“); ,4.5.2 继续继续:在Java中用关键字“continue”表示。在循环体内,用于终止当前的循环,返回到循环开始处,接着开始新的一次循环。 例4-16 程序清单:ContinueTest.java /* *继
28、续循环的测试 */ public class ContinueTest public static void main(String args)for(int i = 1; i 20; i+)if(i % 2 = 0)continue;System.out.print(“ “ + i);System.out.println(“n the Reptation is over!“); ,4.5.3 标签语句在Java中唯一用到标签的地方就是在循环语句之前。“标签”就是一个后面跟有冒号的标识符,如:label:它在代码中应该靠在循环语句的前面,尽量不要在标签与循环语句之间加入任何其他的语句。,例4-
29、17 程序清单:LabeledFor.java /* *标签使用测试 */ public class LabeledFor public static void main(String args)outer:for (int i = 0; i 5; i+)System.out.println(“i = “ + i);inner:for(int j = 0; j 3; j+)System.out.println(“j = “ +j);if(j % 2 = 0)System.out.println(“continue inner“);,continue inner;/中断内部循环体当次循环if(i
30、 % 2 = 1)System.out.println(“continue outer“);continue outer;/中断外部循环体当次循环if( i = 3)System.out.println(“break outer“);break outer;/中断外部循环体System.out.println(“this is all over!“); ,4.6 分支语句,分支语句(switch)有时也被称为“选择语句”、“开关语句”或“多重条件句”。其功能是根据一个整数表达式的值,从一系列代码中选出一段与之相符的执行。它的格式如下:switch(整数选择因子)case 整数值1: 语句; b
31、reak;case 整数值2: 语句; break;case 整数值3: 语句; break;case 整数值4: 语句; break; default: 语句;,例4-18 程序清单:SwitchTest.java /* *分支语句功能测试 */ import java.io.*; public class SwitchTest public static void main(String args)String strIn = “;InputStreamReader in = new InputStreamReader(System.in);BufferedReader buffIn =
32、new BufferedReader(in);System.out.print(“Please enter a month(1-12): “);trystrIn = buffIn.readLine();/从命令行读入数据catch (IOException e)System.out.println(e.toString();int month = Integer.parseInt(strIn);/将字符串转变成整数型,int season = 0;if (month 0)season = (month + 10) % 12)/3 + 1;/计算季节的公式switch(season)case 1
33、:System.out.println(“the season is Spring!“);break;case 2:System.out.println(“the season is Summer!“);break;case 3:System.out.println(“the season is Fall!“);break;case 4:System.out.println(“the season is Winter!“);break;default:System.out.println(“this is not correct month!“); ,例4-19 程序清单:SwitchTest
34、2.java /* *分支语句功能测试 */ import java.io.*; public class SwitchTest2 public static void main(String args)String strIn = “;InputStreamReader in = new InputStreamReader(System.in);BufferedReader buffIn = new BufferedReader(in);System.out.print(“Please enter a month(1-12): “);trystrIn = buffIn.readLine();
35、/从命令行读入数据catch (IOException e)System.out.println(e.toString();,int month = Integer.parseInt(strIn);/将字符串转变成整数型int season = 0;if (month 0)season = (month + 10) % 12)/3 + 1;/计算季节的公式switch(season)case 1:System.out.println(“the season is Spring!“);break;case 2:System.out.println(“the season is Summer!“)
36、;case 3:System.out.println(“the season is Fall!“);case 4:System.out.println(“the season is Winter!“);break;default:System.out.println(“this is not correct month!“); ,例4-20 程序清单:SwitchTest3.java /* *分支语句功能测试 */ import java.io.*; public class SwitchTest3 public static void main(String args)String strI
37、n = “;InputStreamReader in = new InputStreamReader(System.in);BufferedReader buffIn = new BufferedReader(in);System.out.print(“Please enter a singal lower letter: “);trystrIn = buffIn.readLine();/从命令行读入数据catch (IOException e)System.out.println(e.toString();,char letter = strIn.charAt(0);/将字符串转变成字符型数
38、据switch(letter)case a:System.out.println(“the letter is a!“);break;case b:System.out.println(“the letter is b!“);break;case c:System.out.println(“the letter is c!“);break;case d:System.out.println(“the letter is d!“);break;default:System.out.println(“the letter is not between a and d!“); ,分支语句流程图,4.
39、7 返回语句,(1)return 表达式 比如: int method( int num ) if( num 0 )return 1; else if( num = 0 )return 0;return 1; ,在这个方法中我们声明了返回语句的类型为int型,当主程序调用这个方法时,就会得到一个int类型的返回值,值的内容分别根据不同的情况返回1、0或-1。主程序得到子程序的返回值,就从当前方法中退出,返回到调用该方法的语句处,继续程序的执行。,(2)return如果在程序运行过程中,我们只希望调用子程序,并完成子程序的功能,而不需要子程序返回任何数值,那么我们只需要在子程序的结束处加上一条语句return;就可以了。当然用没有返回值的返回语句时,在方法的声明中必须明确声明返回值类型为void。如: public void setValue()value = a * b / 12;return; 当主程序调用该方法时,会将value进行赋值,赋值结束后会返回到主程序。在这种情况下,我们一般不写return语句。即使不写return语句,方法调用完成后,系统也会自动回到方法调用处,接着进行程序的执行。,4.8 小结,在本章中,重点分析了循环与控制的条件语句、循环语句、分支语句等几种表现形式,并通过详细的对比、示例,使读者能对逻辑控制的几种流程有个清楚的认识。,