第3章 Java控制结构、数组和字符串 Java程序的基本控制结构包含顺序、分支和循环3种。顺序结构的执行是按照先后次 序顺次执行,分支结构的执行是根据判定结果选择对应的语句来执行,循环结构的执行是根 据循环条件来决定是否重复执行循环体。本章除了介绍上述内容之外,还将介绍数组和字 符串应用的语法格式。 3.1 顺序结构 3.1.1 语句和语句块 Java程序是由一条条语句组成的,语句就成为其最小的执行单位。 2.3.5节讲到了赋值运算,它实际上就对应着语句,例如inta=9;就是一条赋值语句。 例2-3中出现了两种输出语句: System.out.println(a=a*b); System.out.println(a); 在这两行语句中,前一行有赋值号,需要计算表达式a*b并赋值给变量a;后一行没有 赋值运算符,就把变量a的值返回给输出语句。Java语言也可以将方法的调用写在输出语 句中,例如: System.out.println(Math.sqrt(16)); Java语言的语句块是指用“{}”括起来的语句组,这在语法上将作为一条语句使用。例 如,下面就是一个语句块: { int y=1; y=y+20; } 2.2.3节提到了变量的作用域。有了语句块的定义以后,变量的作用域就可以解释为变 量定义所在的语句块。 语句块可以嵌套。在嵌套时,变量可以定义在语句块的任何位置。外层语句块中定义 的变量既可以在外层使用,也可以在内层使用。也就是说,外层块定义的变量,其作用域涵 盖了内层块,反之则不然。下例出现了此类作用域问题: { int a=3, b=5; { int c=7; c=c-a; } b=b+c; } ·34· 上面的语句块中,外层定义了变量a和b,其作用域是在整个内、外层块的范围中,即内 层块也可以使用a和b,因此语句 c=c-a; 正确。但是,内层块定义的变量c作用域仅限于内层,外层块不可以使用,因此语句 b=b+c; 图3-1 顺序结构的流程图 错误。 3.1.2 顺序结构 和其他结构化程序设计语言类似,Java语言也有顺序结构、 分支结构和循环结构3种基本控制结构。顺序结构的程序在执 行时是按照前后顺序依次执行的,其流程如图3-1所示。 顺序结构在程序设计中用得非常频繁。这种结构的语句比 较简单,但在具体程序中是必不可少的。例1-1~例1-3以及例 2-1~例2-7,都是属于顺序结构的程序。 【例3-1】 顺序结构应用举例。编程,实现交换两个变量的值。 程序代码如下: 1 public class Example3_1 2 { 3 public static void main(String args[]) 4 { 5 int m=1, n=6, t; 6 t=m; 7 m=n; 8 n=t; 9 System.out.println("m="+m); 10 System.out.println("n="+n); 11 } 12 } 程序运行结果如下: m=6 n=1 程序分析如下: 交换两个变量的值要借助第三个变量才能实现。 3.2 分支结构 在例2-7中,用户提供的一元二次方程系数a、b 和c 满足判别式大于0,程序运行后可以 得到两个不相等的实数根。但是,若考虑判别式等于0和小于0的情况,就对应着两根相等和 ·35· 根不存在的结果。此时,需要分不同情形选择不同的语句块来得出结论。仅使用顺序结构无法 实现这样的思路,应用分支结构就成为了编程的关键。许多现实生活中的实例都与分支结构的 思想相对应。例如,打客服电话时话务员会提醒用户选择服务种类;再如使用自助存取现金时, ATM 机会根据提示选择币种,等等。在Java语言中,分支结构主要包括if语句和switch语句。 3.2.1 if语句 if语句有双分支结构和单分支结构,其语法格式如下: if(条件表达式) 语句块1 [else 语句块2 ] 在执行时,先判断条件表达式的值,若为true则执行语句块1,之后执行该if分支结构 的后续语句;否则执行else后面的语句块2。流程如图3-2(a)所示。如果省略else子句,条 件表达式值为true执行语句块1,为false时什么也不做,其流程如图3-2(b)所示。 图3-2 if语句流程图 【例3-2】 比较两个数,求出其中的较大者并输出。若使用双分支的if语句,则程序代 码如下: 1 import java.util.Scanner; 2 public class Example3_2 3 { 4 public static void main(String args[]) 5 { 6 Scanner scan=new Scanner(System.in); 7 System.out.println("请输入两个数:"); 8 double x=scan.nextDouble(); 9 double y=scan.nextDouble(); 10 if(x<y) 11 { 12 System.out.println("两个数中的较大者: "+y); 13 } 14 else ·36· 15 { 16 System.out.println("两个数中的较大者: "+x); 17 } 18 } 19 } 程序运行后,在提示“请输入两个数:”后面输入3.14和2.7,则输出结果如下: 两个数中的较大者: 3.14 程序采用了双分支的if…else… 语句,这是二选一型结构。如果采用单分支if语句,则 需要将上述程序代码进行修改,要将第10~17行替换为下列语句: double max=x; if(x<y) { max= y; }S ystem.out.println("两个数中的较大者: "+max); 程序的运行结果不变。这里if语句仅有一个分支处理,故预设变量max并先将x 的值 赋给它。经过比较,确定调整或不调整max的值,再输出max即可。 【例3-3】 已知下面的分段函数: y= 5x, x≤0 1+2x, x>0 { 设计程序,输入x 得到y 的值。 程序代码如下: 1 import java.util.Scanner; 2 public class Example3_3 3 { 4 public static void main(String args[]) 5 { 6 Scanner scan=new Scanner(System.in); 7 System.out.println("请输入x:"); 8 double x=scan.nextDouble(),y; 9 if(x<=0) 10 { 11 y=5*x; 12 } 13 else 14 { 15 y=1+2*x; 16 } 17 System.out.println("y="+y); 18 } 19 } ·37· 程序运行后,用户若输入0则输出y=0.0;若输入8则输出y=17.0。 本例中的分段函数也是二选一型的,应当用双分支if语句完成。但是,如果分段函数 存在超过两种情形来选择时,使用前面的语句结构就难以完成了,此时可以用if语句的嵌 套形式实现。 3.2.2 if语句的嵌套 if语句的嵌套是指单分支或双分支if语句中,语句块又包含着一重或多重if语句。其 语法格式如下: if<条件表达式> { if <条件表达式> 语句块 [else 语句块 ]} [else { if <条件表达式> 语句块 [else 语句块 ]} ] 嵌套时,语句中的每一个else必须和一个if相对应,以避免产生混乱。 【例3-4】 再计算下面分段函数的值: y= 2x+1, x<2 x-3, 2≤x<8 3x-1, x≥8 ì . í .. .. 程序代码如下: 1 import java.util.Scanner; 2 public class Example3_4 3 { 4 public static void main(String args[]) 5 { 6 Scanner scan=new Scanner(System.in); 7 System.out.println("请输入x:"); 8 double x=scan.nextDouble(),y; 9 if(x<2) 10 { 11 y=2*x+1; 12 } 13 else 14 { if(x<8) 15 y=x-3; ·38· 16 else 17 y=3*x-1; 18 } 19 System.out.println("y="+y); 20 } 21 } 用户在程序运行后,分别输入0,7和9,对应输出结果为1.0,4.0和26.0。该程序使用 了if语句嵌套形式:在else子句部分,又嵌入了if语句,这样建立了三选一型结构。请读者 思考一下:若换作在if和else之间嵌入另外一个if语句,应当如何完成? 3.2.3 多分支if语句 例3-4中的if语句嵌套形式也可以改写为多分支if语句,这种格式看起来比较清晰。 其语法格式如下: if(条件表达式1) 语句块1 else if(条件表达式2) 语句块2 …e lse if(条件表达式n ) 语句块n [else 语句块n +1 ] 多分支If语句的执行过程为,先计算条件表达式1,若条件表达式1的值为true则执行 其后的语句块1,然后执行多分支if结构后面的语句;若条件表达式1的值为false,则判断 条件表达式2的值是否为true,为true则执行其后的语句块2,否则依次继续向下判断。如 果所列出的前n 个条件表达式的值都为false,再看有没有else子句,有则执行它后面的语 句块n+1,若没有则执行该多分支if结构后面的语句。整个流程如图3-3所示。 图3-3 多分支的if语句流程图 ·39· 将例3-4改写为多分支if语句,核心部分如下: if(x<2) y=2*x+1; else if(x<8) y=x-3; else y=3*x-1; 相比于if语句嵌套,这样的程序看起来层次更加分明。例2-7中,将判别式等于0和小 于0的情况都考虑进来,则完整的程序代码如下: 1 import java.util.Scanner; 2 public class Example2_7 3 { 4 public static void main(String args[]) 5 { 6 Scanner scan=new Scanner(System.in); 7 System.out.println("请输入方程的系数a,b,c"); 8 double a=scan.nextDouble(); 9 double b=scan.nextDouble(); 10 double c=scan.nextDouble(); 11 double p,q,delta=b*b-4*a*c; 12 p=-b/(2*a); 13 if(delta<0) 14 System.out.println("该一元二次方程无实数根"); 15 else if(delta==0) 16 { double x=p; 17 System.out.println("该一元二次方程两根相等,x="+x); 18 } 19 else 20 { q=Math.sqrt(delta)/(2*a); 21 double x1=p+q; 22 double x2=p-q; 23 System.out.println("x1="+x1); 24 System.out.println("x2="+x2); 25 } 26 } 27 } 程序运行后,用户若输入1,2和-15则输出结果为“x1=3.0”和“x2=-5.0”;用户若输 入1,4和4则输出结果为“该一元二次方程两根相等,x=-2.0”;用户若输入5,1和2则输 出结果为“该一元二次方程无实数根”。 3.2.4 switch语句 switch语句是Java语言中另一种表示多分支结构的语句,该结构使得此类程序更为简 练,其语法格式如下: ·40· switch(表达式) { case 常量1: 语句块1; [break; ] case 常量2: 语句块2; [break; ] … case 常量n : 语句块n ; [break; ] [default: 语句块n +1; ] } switch语句的执行过程为,先对表达式求值,然后将它逐一与case子句中的常量值相 匹配:如果匹配成功,则执行该case子句中的语句块,直到遇见break才算结束,去执行 switch结构的后续语句。假如某个case子句中没有break,若表达式的值与该case后的常 量值相等,在执行完毕该case子句中的语句块后,要紧接着去执行后继的case子句中的语 句序列,直到遇见break才算结束。如果所有case子句的常量均未能匹配成功,则往下看 有没有default子句,若有就执行语句块n+1,若无就算结束,去执行switch结构的后续语 句。整个流程如图3-4所示。 图3-4 switch语句的流程图 【例3-5】 将数值0~6表示的星期几转换为由英文表示的形式。 程序代码如下: 1 import java.util.Scanner; 2 public class Example3_5 3 { 4 public static void main(String args[]) 5 { 6 Scanner scan=new Scanner(System.in); 7 System.out.println("请输入一个数字(0~6): "); ·41· 8 int when=scan.nextInt(); 9 switch(when) 10 { 11 case 0: System.out.println("Sunday"); break; 12 case 1: System.out.println("Monday"); break; 13 case 2: System.out.println("Tuesday"); break; 14 case 3: System.out.println("Wednesday"); break; 15 case 4: System.out.println("Thursday"); break; 16 case 5: System.out.println("Friday"); break; 17 case 6: System.out.println("Saturday"); break; 18 default: System.out.println("Error Input"); 19 } 20 } 21 } 程序中的switch语句有8个分支,对应着用户输入不同数据的处理结果。 3.3 循环结构 循环是指在程序中有规律地反复执行某一语句块的现象。被重复执行的语句块称为循 环体,循环体的执行与否以及次数多少要视循环类型与条件而定。当然,无论何种类型的循 环结构,其共同的特点是必须确保循环体的重复执行能被终止。 Java的循环语句有for语句,while语句和do语句。 3.3.1 for语句 for语句在循环结构中最常用,属于计数型循环,其语法格式如下: 图3-5 for语句流程图 for ([表达式1];[表达式2];[表达式3]) 循环体语句块 其中,[表达式1]是对循环控制变量初始化操作;[表达 式2]是关系表达式或逻辑表达式,是循环控制条件; [表达式3]用于改变循环控制变量的值。这3个表达 式都可以省略,当[表达式2]省略时就默认该式的值为 true。 for语句运行后,首先执行1式,进行循环控制变量 的初始化。接下来判定2式的真假。如果为真,就去执 行循环体语句块,并且要由3式来修改循环控制变量, 这就完成了一次循环。然后再次判定2式的真假,如果 为真就重复上述过程。这样的操作一直进行下去,直到 2式的值为假时,不再执行下去,整个循环宣告结束,转 向for结构的后续语句。当然,若首次判定2式的值就 为假,则循环一次也不会执行。上述过程如图3-5 ·42· 所示。 【例3-6】 求1+2+3+…+10的值。 程序代码如下: 1 public class Example3_6 2 { 3 public static void main(String args[]) 4 { 5 int sum=0; 6 for(int i=1;i<=10;i++) 7 sum=sum+i; 8 System.out.println("1+2+3+…+10="+sum); 9 } 10 } 程序运行结果如下: 1+2+3+…+10=55 本例题编程实现起来较为简单,理解了累加的思想就能顺利完成,第7行代码是关键。 【例3-7】 求Fibonacci数列前9项的值。已知Fibonacci数列为1,1,2,3,5,……该数 列有如下特点:第1项、第2项均为1,从第3项开始,每一项都是前两项之和,即 Fn = 1, n =1 1, n =2 Fn-1 +Fn-2, n ≥3 ì . í .. .. 程序代码如下: 1 public class Example3_7 2 { 3 public static void main(String args[]) 4 { 5 int x1=1, x2=1, x3; 6 System.out.println("数列第1 项: "+x1); 7 System.out.println("数列第2 项: "+x2); 8 for(int i=3;i<=9;i++) 9 { 10 x3=x1+x2; 11 System.out.println("数列第"+i+"项: "+x3); 12 x1=x2; 13 x2=x3; 14 } 15 } 16 } 程序运行结果如下: 数列第1 项: 1 ·43· 数列第2 项: 1 数列第3 项: 2 数列第4 项: 3 数列第5 项: 5 数列第6 项: 8 数列第7 项: 13 数列第8 项: 21 数列第9 项: 34 程序分析如下: 定义变量x1代表第1项,x2代表第2项。x3代表第3项的值,它由x1+x2求得(代码 第10行)。当首轮计算完成后,x2成为第1项(代码第12行),x3成为第2项(代码第13 行),然后进行下一轮的运算。继续后面各轮循环,直到最后计算出第九项的值,这样就得到 了全部结果。 【例3-8】 如果一个三位数等于其各位数字的立方和,则称这个数为水仙花数,例如 153=13+53+33,371=33+73+13。试编程找出所有的水仙花数。 程序代码如下: 1 public class Example3_8 2 { 3 public static void main(String args[]) 4 { 5 int x, y, z, k; 6 System.out.println("全部水仙花数: "); 7 for(int i=100; i<=999; i++) 8 { 9 x=i/100; 10 y=i/10-x*10; 11 z=i-x*100-y*10; 12 k=x*x*x+y*y*y+z*z*z; 13 if(i==k) 14 { 15 System.out.print(i+" "); 16 } 17 } 18 } 19 } 程序运行结果如下: 全部水仙花数: 153 370 371 407 程序分析如下: 100,101,102,…,999,每个数均要被检测。设每轮要测试的数为i。针对判断条件,求 出待测试数据i的百位(代码第9行)、十位(代码第10行)和个位(代码第11行)的数字,看 ·44· 看是否符合水仙花数的条件(代码第12、13行)。再一轮要测试加1之后的i,如此循环900 轮,完成对全部三位数的检测。 3.3.2 while语句 循环结构中for语句一般用于循环次数可预知的情形。然而,编程时往往存在循环次 数无法确定、要通过条件终止循环的状况,此时可以采用while语句来实现。while语句属 于条件型循环,它根据某一条件进行判断,决定是否执行循环。其语法格式如下: while(布尔型表达式) 循环体语句块 while语句执行时,如果布尔型表达式的值为true,则执行循环体语句块;否则退出循 图3-6 while语句流程图 环。其执行流程如图3-6所示。 实际编程中,循环体语句块在执行时应能使条件发生改 变,以确保布尔型表达式的值最终可以出现false,否则会出现 死循环。 【例3-9】 我国现有人口13亿,求按照年增长率1.2%计 算,需要多少年后我国人口超过20亿。 程序代码如下: 1 public class Example3_9 2 { 3 public static void main(String args[]) 4 { 5 double p =13, r =0.012; 6 int i =0; 7 while(p<=20) 8 { 9 p =p * (1 +r); 10 i =i +1; 11 } 12 System.out.println(i+"年后,我国人口达到"+p+"亿"); 13 } 14 } 程序运行结果如下: 37 年后,我国人口达到20.212606208344745 亿 程序分析如下: 定义变量p表示人口数并赋初值为13(亿),变量r表示增长率并赋初值为0.012,变量i 表示经过多少年。while语句的循环体主要来计算人口每过一年以后的数量(代码第9行), 并且要修改循环控制变量i的值(代码第10行)。 【例3-10】 求满足1+2+3+…+n≥1000时,n 的最小值。 程序代码如下: ·45· 1 public class Example3_10 2 { 3 public static void main(String args[]) 4 { 5 int n =0, sum =0; 6 while(sum <1000) 7 { 8 n =n +1; 9 sum =sum +n; 10 } 11 System.out.println("sum="+sum+" "+"n="+n); 12 } 13 } 程序运行结果如下: sum=1035 n=45 程序分析如下: 题目要用累加的思路来解决,设计条件型循环,第6行代码对应着循环控制条件。 3.3.3 do语句 do语句与while语句较为相似,具有如下的语法格式: do 循环体语句块; while(布尔型表达式) do语句的特点是首先要执行一次循环体语句块,再去判断表达式是否为真。若为真则 继续执行循环体,否则退出do循环结构。因此,do语句的循环体至少被执行一次。 【例3-11】 已知π的近似值可用如下公式表示: π 4 ≈1-13 +15 -17+ … + (-1)n-1 1 2n -1 利用该公式求π,要求最后一项的绝对值小于0.00000001。 程序代码如下: 1 public class Example3_11 2 { 3 public static void main(String args[]) 4 { 5 double r=0, sum=0; 6 int i=1,j=-1; 7 do 8 { j=j*(-1); 9 r=(double)1/(2*i-1); 10 r=r*j; ·46· 11 sum=sum+r; 12 i=i+1; 13 } 14 while((Math.abs(r)) >=0.00000001); 15 sum=sum*4; 16 System.out.println("π的近似值为: "+sum); 17 } 18 } 程序运行结果如下: π的近似值为: 3.1415926735902504 程序分析如下: 编程所采用的思路仍然是累加,代码第11行是关键。代码第8~10行都是为正确求得 累加和所做的处理。 3.3.4 循环嵌套 3.3.1~3.3.3节介绍的都是单层循环。实际应用中常涉及在循环体语句块内又包含其 他循环的结构。一个循环结构中又包含一个或多个循环结构被称为循环嵌套,或称多重 循环。设 计多重循环时,往往根据需要确定嵌套的层数。有几层嵌套,就称为几重循环,如二 重循环、三重循环等。循环嵌套的执行过程是,外层循环每执行一次,内层循环要从头到尾 执行一遍。 设计循环嵌套时要注意,内层循环变量与外层循环变量不能同名。 为了增强可读性,循环嵌套的程序应当采用缩进方式书写代码,也就是要使程序具有锯 齿形样式。 【例3-12】 将例3-8用循环嵌套的思路重新设计。 1 public class Example3_12 2 { 3 public static void main(String args[]) 4 { 5 int i=1, j, h, k; 6 System.out.println("全部水仙花数: "); 7 while(i<=9) 8 { 9 j=0; 10 while(j<=9) 11 { 12 h=0; 13 while(h<=9) 14 { 15 k=i*i*i+j*j*j+h*h*h; 16 if(k==100*i+10*j+h) ·47· 17 { 18 System.out.print(k+" "); 19 } 20 h++; 21 } 22 j++; 23 } 24 i++; 25 } 26 } 27 } 程序运行结果不变。 程序分析如下: 定义变量i、j、k分别代表百位、十位、个位数字,使用三重循环产生100~999的整数,最 内层循环(第15~20行代码)用于判定当前的三位数是否符合水仙花数的规则。 【例3-13】 用循环嵌套语句生成如图3-7所示的图形。 ## ## ##### ####### ######### ########### ############# ############### ################# ################### 图3-7 循环嵌套程序运行结果 程序代码如下: 1 public class Example3_13 2 { 3 public static void main(String args[]) 4 { 5 int i=1, j=1; 6 do 7 { 8 j=1; 9 do 10 { 11 System.out.print("#"); 12 j++; 13 } 14 while(j<=2*i-1); ·48· 15 System.out.print("\n"); 16 i++; 17 } 18 while(i<=10); 19 } 20 } 程序分析如下: 设计循环嵌套结构,外层循环变量i的值从1变化到10,一共10轮;内层循环变量j的 值从1变化到“2*i-1”,控制输出“2*i-1”个“#”。 【例3-14】 打印如下的九九乘法表。 1*1=1 1*2=2 1*3=3 1*4=4 1*5=5 1*6=6 1*7=7 1*8=8 1*9=9 2*1=2 2*2=4 2*3=6 2*4=8 2*5=10 2*6=12 2*7=14 2*8=16 2*9=18 3*1=3 3*2=6 3*3=9 3*4=12 3*5=15 3*6=18 3*7=21 3*8=24 3*9=27 4*1=4 4*2=8 4*3=12 4*4=16 4*5=20 4*6=24 4*7=28 4*8=32 4*9=36 5*1=5 5*2=10 5*3=15 5*4=20 5*5=25 5*6=30 5*7=35 5*8=40 5*9=45 6*1=6 6*2=12 6*3=18 6*4=24 6*5=30 6*6=36 6*7=42 6*8=48 6*9=54 7*1=7 7*2=14 7*3=21 7*4=28 7*5=35 7*6=42 7*7=49 7*8=56 7*9=63 8*1=8 8*2=16 8*3=24 8*4=32 8*5=40 8*6=48 8*7=56 8*8=64 8*9=72 9*1=9 9*2=18 9*3=27 9*4=36 9*5=45 9*6=54 9*7=63 9*8=72 9*9=81 程序代码如下: 1 public class Example3_14 2 { 3 public static void main(String args[]) 4 { 5 System.out.println("九九乘法表"); 6 for(int i=1;i<=9;i++) 7 { 8 for(int j=1;j<=9;j++) 9 { 10 System.out.print(i +"*" +j +"=" +i*j); 11 if(i*j<=9) 12 { 13 System.out.print(" "); 14 } 15 else 16 { 17 System.out.print(" "); 18 } 19 } 20 System.out.print("\n"); 21 } 22 } 23 } ·49· 程序运行将输出题目要求的结果。程序设计了二重循环,第6行代码对应外层循环,用于 行循环变量的控制(i:1~9);第8行代码对应内层循环,用于列循环变量的控制(j:1~9)。外 层每循环1轮,内层要循环9次。第10行代码是关键,用于产生乘法公式。第11~18行代 码属于输出格式调整语句,用于使同一列上下对齐,其中第13行输出两个空格,第17行输 出一个空格。也可以将第11~18行代码删去,同时将第10行代码改为 System.out.print(i+"*"+j+"="+i*j+"\t"); 也可以达到同样的效果,而且整个程序显得更为简练。 3.4 转移语句 转移语句有两个:break语句和continue语句。 3.4.1 break语句 在3.2.4节中已经出现了关键字break,其作用是跳出switch部分,转向多分支结构后 面的语句。在循环结构中也可以添加break语句,这时候它的作用是跳出循环体。应当注 意,break只能跳出其所在的最内层循环体。如果需要跳出多重循环,则要使用带标号的 break语句。其语法格式如下: break [标号]; 【例3-15】 将例3-10用含有break语句的循环结构实现。 程序代码如下: 1 public class Example3_15 2 { 3 public static void main(String args[]) 4 { 5 int n=0, sum=0; 6 while(true) 7 { 8 n++; 9 sum+=n; 10 if(sum>1000) 11 break; 12 } 13 System.out.println("n="+n+" "+"sum="+sum); 14 } 15 } 程序运行结果如下: n=45 sum=1035 可以看到,使用含break语句的循环结构解决一些问题比较方便。 ·50· 在多重循环中,若要连跳几层,甚至直接跳出最外层,则要使用带标号的break语句, 例如: label1: while(…) { while(…) { for(…) { if(…) break label1; } } } 3.4.2 continue语句 continue语句和break语句相比,它不是跳出循环体,而是中断执行当前循环体的剩余 部分,并准备进入下一轮循环。其语法格式如下: continue [标号]; 【例3-16】 用含有continue语句的循环结构求1~100的所有奇数和。 程序代码如下: 1 public class Example3_16 2 { 3 public static void main(String args[]) 4 { 5 int total=0, i; 6 for(i=1; i<=100; i++) 7 { 8 if(i %2 ==0) 9 continue; 10 total+=i; 11 } 12 System.out.println("total="+total); 13 } 14 } 程序运行结果如下: total=2500 程序分析如下: 当i为偶数时,continue语句将使得程序跳转。此时循环体语句块的剩余部分(第10 行代码)不再执行,转向执行将循环控制变量i的值加1,再判断是否进行下一轮循环。 ·51· 3.5 数 组 Java中有序数据的集合可以用数组来表示,一般一个数组中的元素属于同一种数据类 型。数组在内存中对应着一段连续存储区域,数组名是这块区域的起始地址。利用数组名 和下标可以方便地访问每一个数组元素。数组下标从0开始,数组的长度即为数组元素的 个数。数组根据其下标个数的不同分为一维数组、二维数组和多维数组,这里重点介绍前 两种。 3.5.1 数组的声明 从上一个程序中可以看到,如果首次使用变量i,要通过语句inti;和i=1;来完成声明 和初始化操作,也可以通过语句inti=1来完成。类似地,首次使用一个数组也需要先声明 和初始化。 1.声明一维数组 声明一维数组的语法格式有两种: 类型 数组名[]; 类型[] 数组名; 这两种格式的作用相同。其中,类型对应于Java语言中的任意数据类型;数组名应当 是一个合法的标识符,[]表明这是个数组类型的变量。例如: double a[]; long array1[], array2[]; 前者声明了一个double型的数组a,后者声明了两个long型的数组array1和array2。 它们也可以写成下面的格式: double[]a; long[]array1, array2; 2.声明二维数组 声明二维数组的语法格式有3种: 类型数组名[][]; 类型[][]数组名; 类型[]数组名[]; 例如,下面声明了3个short型二维数组,采用的是3种不同的格式: short Arr1[][]; short[][]Arr2; short[]Arr3[]; 3.5.2 数组的初始化 数组被声明后,仅代表想创建一个数组,系统并没有为其分配内存储空间。只有将数组 ·52· 初始化以后,才标志着以数组名为内存首地址的一段连续存储区域被分配给数组。数组的 初始化有两种:静态初始化和动态初始化。 1.静态初始化 在声明数组后,直接对其赋值,根据值的类型及个数,系统为它分配内存储区域,并保存 下来首地址,这就是数组的静态初始化。例如,一维数组的静态初始化如下: float price[]; price={13.7f, 28.8f, 30.2f}; 上述语句创建了数组price,含有3个float型的下标变量,并为其分配内存储区域,它 们是price[0]、price[1]和price[2],对应的值为13.7f、28.8f和30.2f。 另外,采用将数组声明和初始化合并的写法,会显得较为简练。例如,将上面两行代码 合并为: float price[]={13.7f,28.8f,30.2f}; 【例3-17】 对二维数组进行静态初始化,再输出全部数组元素。 1 public class Example3_17 2 { 3 public static void main(String args[]) 4 { 5 int array[][]={{6,2,7}, {5,2,0}, {3,9,1}}; 6 for(int i=0; i<=2; i++) 7 { 8 for(int j=0; j<=2; j++) 9 { 10 System.out.print("array"+"["+i+"]"+"["+j+"]"+"="); 11 System.out.print(array[i][j]+" "); 12 } 13 System.out.print("\n"); 14 } 15 } 16 } 程序运行结果如下: array[0][0]=6 array[0][1]=2 array[0][2]=7 array[1][0]=5 array[1][1]=2 array[1][2]=0 array[2][0]=3 array[2][1]=9 array[2][2]=1 程序分析如下: 第5行代码完成了对二维数组array的声明和静态初始化操作。由此可知,数组array 第一维和第二维的长度均为3,故一共包含9个int型的下标变量,它们是array[0][0]、 array[0][1]、array[0][2]、array[1][0]、array[1][1]、array[1][2]、array[2][0]、array[2][1]和 array[2][2]。第6~14行代码用于输出这9个数组元素,采用二重循环结构,设计了3行3列 的显示样式。第13行代码用于换行。 ·53·