java编程思想_控制执行流程_0401

第4章 控制执行流程

程序必须在执行过程中控制它的世界,并做出选择。在Java中使用执行控制语句来做出选择。

4.1true和false

条件语句利用条件表达式的真或假来决定执行路径。

例如条件表达式a==b,用条件操作符“==”来判断a值是否等于b值。该表达式返回true或false。

Java不允许将一个数字作为布尔值使用,

4.2if-else

if-else语句,控制程序流程。

else是可选的,可按下述两种形式来使用if:

if(Boolean-expression)

statement

if(Boolean-expression)

statement

else

statement

布尔表达式必须产生一个布尔结果。

statement指用分号结尾的简单语句,或复合语句(封闭在花括号内的一组简单语句)。

例:test(),您猜的是大于,小于还是等于目标数。

 1 //:control/IfElse.java
 2 package control;
 3 import static util.Print.*;
 4 
 5 public class IfElse {
 6     static int result=0;
 7     static void test(int testval,int target) {
 8         if(testval>target)
 9             result=+1;
10         else if(testval<target)
11             result=-1;
12         else
13             result=0;//Match
14     }
15 
16     public static void main(String[] args) {
17         test(10,5);
18         print(result);
19         test(5,10);
20         print(result);
21         test(5,5);
22         print(result);
23     }
24 
25 }

Output:

 

 else if不是新的关键字,仅仅是一个else后面紧跟另一个新的if语句。

Java是格式自由的语言,但是习惯上将流程控制语句的主体部分缩进排列,使读者能方便地确定起始与终止。

4.3迭代

while、do-while和for用来控制循环,有时将它们划分为迭代语句(iteration statement)。

语句会重复执行,直到起控制作用的布尔表达式得到“假”的结果为止。

while循环的格式如下:

while(Boolean-expression)

statement

在循环刚开始时,会计算一次布尔表达式的值;

而在语句的下一次迭代开始前会再计算一次。

例:下面这个例子可产生随机数,直到符合特定的条件为止:

 1 //:control/WhileTest.java
 2 //Demonstrates the while loop.
 3 package control;
 4 
 5 public class WhileTest {
 6     static boolean condition() {
 7         boolean result=Math.random()<0.99;
 8         System.out.print(result+",");
 9         return result;
10     }
11 
12     public static void main(String[] args) {
13         while(condition())
14             System.out.println("Inside 'while'");
15         System.out.println("Exited 'while'");
16 
17     }
18 
19 }

Output:

 Math库里的static方法random(),产生0和1之间(包括0,但不包括1)的一个double值。

result的值是通过比较操作符<而得到它,这个操作符将产生boolean类型的结果。

while条件语句,只要condition()返回true,就重复执行循环体中的语句。

4.3.1do-while

do-while的格式如下:

do

statement

while(Boolean-expression);

do-while中的语句至少会执行一次。

4.3.2for

for循环可能是最经常使用的迭代形式,这种在第一次迭代之前要进行初始化。

随后,它会进行条件测试,而且在每一次迭代结束时,进行某种形式的“步进”。

for循环的格式如下:

for(initialization;Boolean-expression;step)

statement

初始化表达式,布尔表达式,或者步进运算都可以为空。

每次迭代前会测试布尔表达式。若获得的结果是true,就会执行for语句后面的代码行。每次循环结束,会执行一次步进。

例:for循环用于执行“计数”任务:

 1 //:control/ListCharacters.java
 2 //Demonstrates "for" loop by listing
 3 //all the lowercase ASCII letters.
 4 package control;
 5 
 6 public class ListCharacters {
 7 
 8     public static void main(String[] args) {
 9         for(char c=0;c<128;c++)
10             if(Character.isLowerCase(c))
11                 System.out.println("value:"+(int)c+"character:"+c);
12 
13     }
14 
15 }

Output:

 

 变量c是在for循环的控制表达式里被定义的。c的作用域就是for控制的表达式的范围内。

这里用到了java.lang.Character包装器类,这个类不但能把char基本类型的值包装进对象,还提供了一些别的有用的方法。这里用到了static isLowerCase()方法来检查问题中的字符是否为小写字母。

C语言,要求所有变量都在一个块的开头定义,以便编译器在创建这个块的时候,可以为那些变量分配空间。

在Java和C++中,则可在整个块的范围内分散变量申明,在真正需要的地方才加以定义。这样便可形成更自然的编码风格,也更易理解。

练习1:

(1)写一个程序,打印从1到100的值。

 1 package control;
 2 
 3 public class CoTest1 {
 4 
 5     public static void main(String[] args) {
 6         for(int i=0;i<100;i++)
 7             System.out.println((i+1));
 8 
 9     }
10 
11 }

Output:

 

 练习2:

(2)写一个程序,产生25个int类型的随机数。对于每一个随机值,使用if-else语句来将其分类为大于、小于,或等于紧随它而随机生成的值。

 1 package control;
 2 
 3 public class CoTest2 {
 4 
 5     public static void main(String[] args) {
 6         int a[]=new int[25];
 7         for(int i=0;i<25;i++) {
 8             a[i]=(int)(Math.random()*100);
 9             
10             
11         }
12         for(int j=0;j<24;j++) {
13             if(a[j]>a[j+1])
14                 System.out.println("第"+(j+1)+"个数"+a[j]+">第"+(j+2)+"个数"+a[j+1]);
15             else if(a[j]<a[j+1])
16                 System.out.println("第"+(j+1)+"个数"+a[j]+"<第"+(j+2)+"个数"+a[j+1]);
17             else
18                 System.out.println("第"+(j+1)+"个数"+a[j]+"=第"+(j+2)+"个数"+a[j+1]);
19         }
20             
21         
22 
23     }
24 
25 }

Output:

 

 

 练习3:

修改练习2,把代码用一个while无限循环包括起来。然后运行它直至用键盘中断其运行(通常是通过按Ctrl-C)。

 1 package control;
 2 
 3 public class CoTest3 {
 4 
 5     public static void main(String[] args) {
 6         int a[]=new int[25];
 7         while(true) {
 8         for(int i=0;i<25;i++) {
 9             a[i]=(int)(Math.random()*100);
10             
11             
12         }
13         for(int j=0;j<24;j++) {
14             if(a[j]>a[j+1])
15                 System.out.println("第"+(j+1)+"个数"+a[j]+">第"+(j+2)+"个数"+a[j+1]);
16             else if(a[j]<a[j+1])
17                 System.out.println("第"+(j+1)+"个数"+a[j]+"<第"+(j+2)+"个数"+a[j+1]);
18             else
19                 System.out.println("第"+(j+1)+"个数"+a[j]+"=第"+(j+2)+"个数"+a[j+1]);
20         }
21         }
22             
23     }
24 
25 }

Output:

 

 练习4:

(3)写一个程序,使用两个嵌套的for循环和取余操作符(%)来探测和打印素数(只能被其自身和1整除,而不能被其他数字整除的整数)。

练习5:

(4)重复第3章中的练习10,不要用Integer.toBinaryString()方法,而是用三元操作符和按位操作符来显示二进制的1和0。

4.3.3逗号操作符

逗号分隔符,用来分隔函数的不同参数。

逗号操作符,Java里唯一用到逗号操作符的地方就是for循环的控制表达式。

在控制表达式的初始化和步进控制部分,可以使用一系列由逗号分隔的语句;而且那些语句均会独立执行。

通过使用逗号操作符,可以在for语句内定义多个变量,但是它们必须具有相同的类型。

 1 //:control/CommaOperator.java
 2 package control;
 3 
 4 public class CommaOperator {
 5 
 6     public static void main(String[] args) {
 7         // TODO Auto-generated method stub
 8         for(int i=1,j=i+10;i<5;i++,j=i*2) {
 9             System.out.println("i="+i+"j="+j);
10         }
11 
12     }
13 
14 }

Output:

 

 for语句中的int定义涵盖了i和j,在初始化部分实际上可以拥有任意数量的具有相同类型的变量定义。

无论在初始化还是在步进部分,语句都是顺序执行的。

初始化部分可以有任意数量的同一类型的定义。

4.4Foreach语法

Java SE5引入,一种新的更加简洁的for语法用于数组和容器。

即foreach语法,不必创建int变量去对由访问项构成的序列进行计数,foreach将自动产生每一项。

例:假设有一个float数组,我们要选取该数组中的每一个元素:

 1 //:control/ForEachFloat.java
 2 package control;
 3 import java.util.*;
 4 
 5 public class ForEachFloat {
 6 
 7     public static void main(String[] args) {
 8         Random rand=new Random(47);
 9         float f[]=new float[10];
10         for(int i=0;i<10;i++)
11             f[i]=rand.nextFloat();
12         for(float x:f)
13             System.out.println(x);
14 
15     }
16 
17 }

Output:

 

 这个数组是用旧式的for循环组装的,因为在组装时必须按索引访问它。

foreach语法:

for(float x:f){

这条语句定义了一个float类型的变量x,继而将每一个f的元素赋值给x。

任何返回一个数组的方法都可以使用foreach。

例如,String类有一个方法toCharArray(),它返回一个char数组,因此可以像下面这样迭代在字符串里面的所有字符:

 1 //:control/ForEachString.java
 2 package control;
 3 
 4 public class ForEachString {
 5 
 6     public static void main(String[] args) {
 7         for(char c:"An African Swallow".toCharArray())
 8             System.out.print(c+" ");
 9 
10     }
11 
12 }

Output:

 

 foreach还可用于任何Iterable对象。

许多for语句都会在一个整型值序列中步进,就像下面这样:

for(int i=0;i<100;i++)

对于这些语句,foreach语法将不起作用,除非先创建一个int数组。

我在net.mindview.util.Range包中创建了一个名为range()的方法,它可以自动地生成恰当的数组。

我的目的是将range()用做static导入:

 1 //:control/ForEachInt.java
 2 package control;
 3 import static util.Range.*;
 4 import static util.Print.*;
 5 
 6 public class ForEachInt {
 7 
 8     public static void main(String[] args) {
 9         for(int i:range(10))//0..9
10             printnb(i+" ");
11         print();
12         for(int i:range(5,10))//5..9
13             printnb(i+" ");
14         print();
15         for(int i:range(5,20,3))//5..20 step3
16             printnb(i+" ");
17         print();
18 
19     }
20 
21 }

range()方法已经被重载,重载表示相同的方法名可以具有不同的参数列表。

range()的第一种重载形式是从0开始产生值,直至范围的上限,但不包括该上限。

第二种形式从第一个值开始产生值,直至比第二个值小1的值为止。

第三种形式有一个步进值,因此它每次的增量为该值。

range()使得foreach语法可以适用于更多的场合,并且这样做似乎可以增加可读性,但是它的效率会稍许降低,因此如果您在做性能调优,也许应该使用仿真器来做评价,它是一种可以度量代码性能的工具。

除了print()之外,我们还使用了printnb()。printnb()方法不会换行,因此可以使用它将一行拆分成多个片段输出。

foreach语法不仅在录入代码时可以节省时间,它阅读起来也要容易得多。

它说明您正在努力做什么(例如获取数组中的每一个元素),而不是给出你正在如何做的细节(例如正在创建索引,因此可以使用它来选取数组中的每一个元素)。在本书中,我们只要有可能就会使用foreach语法。

4.5return

Java中的多个关键词表示无条件分支,它们只是表示这个分支无需任何测试即可发生。这些关键词包括return,break,continue和一种与其他语言中的goto类似的跳转到标号语句的方式。

return关键词有两方面的用途:

一方面指定一个方法返回什么值(假设它没有void返回值),另一方面它会导致当前的方法退出,并返回那个值。

 1 //:control/IfElse2.java
 2 package control;
 3 import static util.Print.*;
 4 
 5 public class IfElse2 {
 6     static int test(int testval,int target) {
 7         if(testval>target)
 8             return +1;
 9         else if(testval<target)
10             return -1;
11         else
12             return 0;//Match
13     }
14 
15     public static void main(String[] args) {
16         print(test(10,5));
17         print(test(5,10));
18         print(test(5,5));
19 
20     }
21 
22 }

Output:

 

 不必加上else,因为方法在执行了return后不再继续执行。

如果在返回void的方法中没有return语句,那么在该方法的结尾处会有一个隐式的return,因此在方法中并非总是必须要有一个return语句。但是,如果一个方法声明它将返回void之外的其他东西,那么必须确保每一条代码路径都将返回一个值。

练习6:

(2)修改前两个程序中的两个test()方法,让它们接受两个额外的参数begin和end,这样在测试testval时将判断它是否在begin和end之间(包括begin和end)的范围内。

 1 package control;
 2 import static util.Print.*;
 3 
 4 public class CoTest61 {
 5     static int result=0;
 6     static char c;
 7     static void test(int testval,int target,int begin,int end) {
 8         if(testval>target)
 9             result=+1;
10         else if(testval<target)
11             result=-1;
12         else
13             result=0;//Match
14         if(testval>=begin&&testval<=end)
15             c='Y';
16             else
17                 c='N';
18     }
19 
20     public static void main(String[] args) {
21         test(10,5,9,13);
22         print(result);
23         print(c);
24         test(5,10,9,13);
25         print(result);
26         print(c);
27         test(5,5,9,13);
28         print(result);
29         print(c);
30     }
31 
32 }

Output:

 

 

 1 package control;
 2 import static util.Print.*;
 3 
 4 public class CoTest62 {
 5     static char test(int testval,int begin,int end) {
 6         if(testval>=begin&&testval<=end)
 7             return 'Y';
 8         
 9         else
10             return 'N';
11     }
12 
13     public static void main(String[] args) {
14         print(test(10,9,13));
15         print(test(5,9,13));
16         print(test(5,9,13));
17 
18     }
19 
20 }

Output:

 

 4.6 break和continue

在任何迭代语句的主体部分,都可用break和continue控制循环的流程。

break用于强行退出循环,不执行循环中剩余的语句。

continue停止执行当前的迭代,然后退回循环起始处,开始下一次迭代。

break和continue在for和while循环中的例子。

 1 //:control/BreakAndContinue.java
 2 //Demonstrates break and continue keywords.
 3 package control;
 4 import static util.Range.*;
 5 
 6 public class BreakAndContinue {
 7 
 8     public static void main(String[] args) {
 9         for(int i=0;i<100;i++) {
10             if(i==74)break;//Out of for loop
11             if(i%9!=0) continue;//Next iteration
12             System.out.print(i+" ");
13         }
14         System.out.println();
15         //Using foreach:
16         for(int i:range(100)) {
17             if(i==74) break; //Out of for loop
18             if(i%9!=0)continue;//Next iteration
19             System.out.print(i+" ");
20         }
21         System.out.println();
22         int i=0;
23         //An "infinite loop":
24         while(true) {
25             i++;
26             int j=i*27;
27             if(j==1269)break;//Out of loop
28             if(i%10!=0)continue;//Top of loop
29             System.out.print(i+" ");
30         }
31 
32     }
33 
34 }
 1 //:control/BreakAndContinue.java
 2 //Demonstrates break and continue keywords.
 3 package control;
 4 import static util.Range.*;
 5 
 6 public class BreakAndContinue {
 7 
 8     public static void main(String[] args) {
 9         for(int i=0;i<100;i++) {
10             if(i==74)break;//Out of for loop
11             if(i%9!=0) continue;//Next iteration
12             System.out.print(i+" ");
13         }
14         System.out.println();
15         //Using foreach:
16         for(int i:range(100)) {
17             if(i==74) break; //Out of for loop
18             if(i%9!=0)continue;//Next iteration
19             System.out.print(i+" ");
20         }
21         System.out.println();
22         int i=0;
23         //An "infinite loop":
24         while(true) {
25             i++;
26             int j=i*27;
27             if(j==1269)break;//Out of loop
28             if(i%10!=0)continue;//Top of loop
29             System.out.print(i+" ");
30         }
31 
32     }
33 
34 }

在这个for循环中,i的值永远不会达到100;因为一旦i到达74,break语句就会中断循环。

通常,只有在不知道中断条件何时满足时,才需要这样使用break。只要i不能被9整除,continue语句就会使执行过程返回到循环的最开头(这使i值递增)。如果能够整除,则将值显示出来。

第二种for循环展示了foreach用法,它将产生相同的结果。

“无穷while循环”的情况,循环内部有一个break语句,可终止循环。除此之外,大家还会看到continue语句执行序列移回到循环的开头,而没有去完成continue语句之后的所有内容。(只有在i值能被10整除时才打印出值。)

无穷循环的第二种形式是for(;;).编译器将while(true)和for(;;)看作是同一回事。

练习7:

(1)修改本章练习1,通过使用break关键词,使得程序在打印到99时退出。然后尝试使用return来达到相同的目的。

 1 package control;
 2 
 3 public class CoTest7 {
 4 
 5     public static void main(String[] args) {
 6         for(int i=0;i<100;i++) {
 7             if(i==99)break;
 8             System.out.println((i+1));
 9         }
10 
11     }
12 
13 }

Output:

 

 

 1 package control;
 2 
 3 public class CoTest7 {
 4 
 5     public static void main(String[] args) {
 6         for(int i=0;i<100;i++) {
 7             if(i==99)return;
 8             System.out.println((i+1));
 9         }
10 
11     }
12 
13 }

Output:

 

 

 

 

 

 

 

 


 

posted @ 2022-04-23 14:59  默默的小漠漠  阅读(66)  评论(0)    收藏  举报