程序流程控制 流程控制语句是用来控制程序中各语句执行顺序的语句,可以把语句组合成能完成一定功能的小逻辑模块。流程控制方式采用结构化程序设计中规定的三种基本流程结构,即顺序结构,分支结构和循环结构。
顺序结构:程序从上到下逐行地执行,中间没有任何判断和跳转
分支结构:根据条件选择性地执行某段代码,有if…else和switch-case两种分支语句
循环结构:根据循环条件,重复性的执行某段代码,有while、do…while、for三种循环语句,JDK1.5提供了foreach循环,方便的遍历集合、数组元素
分支结构 if-else
条件表达式必须是布尔表达式(关系表达式或逻辑表达式)、布尔变量
语句块只有一条执行语句时,一对{}可以省略,但建议保留
当if-else结构是“多选一”时,最后的else是可选的,根据需要可以省略
当多个条件是“互斥”关系时,条件判断语句及执行语句间顺序无所谓
当多个条件是“包含”关系时,“小上大下 / 子上父下”
if-else语句结构,根据需要可以嵌套使用
if语句的三种格式 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 if (条件表达式){ 执行代码块; } if (条件表达式){ 执行代码块1 ; }else { 执行代码块2 ; } if (条件表达式1 ){ 执行代码块1 ; } else if (条件表达式2 ){ 执行代码块2 ; } …… else { 执行代码块n; }
练习 1.假设你想开发一个玩彩票的游戏,程序随机地产生一个两位数的票,提示用户输入一个两位数,然后按照下面的规则判定用户是否能赢。 1)如果用户输入的数匹配彩票的实际顺序,奖金10 000美元 2)如果用户输入的所有数字匹配彩票的所有数字,但顺序不一致,奖金3000美元 3)如果用户输入的一个数字仅满足顺序情况下匹配彩票的一个数字,奖金1000美元 4)如果用户输入的一个数字仅满足非顺序情况下匹配彩票的一个数字,奖金500美元 5)如果用户输入的数字没有匹配任何一个数字,则彩票作废
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 import java.util.Scanner;class Exer1 { public static void main (String[] args) { Scanner scan = new Scanner (System.in); System.out.println("请输入两位数字(10-99):" ); int guess = scan.nextInt(); int guessGe = guess % 10 ; int guessShi = guess/10 ; int number = (int )(Math.random() * 90 ) + 10 ; int numberGe = number % 10 ; int numberShi = number /10 ; if (guess == number){ System.out.println("奖金10000美元" ); }else if (guessGe == numberShi && numberGe == guessShi){ System.out.println("奖金3000美元" ); }else if (guessGe == numberGe || numberShi == guessShi){ System.out.println("奖金1000美元" ); }else if (guessGe == numberShi || numberGe == guessShi){ System.out.println("奖金500美元" ); }else { System.out.println("未中奖" ); } System.out.println("中奖号码是:" + number); } }
主要问题是产生随机数 Math.random() 产生[0,1)范围的随机值 Math.random() * 90:[0,90) Math.random() * 90 + 10:[10,100) 即得到 [10,99] 使用(int)(Math.random() * 90) + 10 产生一个两位数的随机数 公式:[a,b]:(int)(Math.random() * (b - a + 1) )+ a
2.大家都知道,男大当婚,女大当嫁。那么女方家长要嫁女儿,当然要提出一定的条件: 高:180cm以上;富:财富1千万以上;帅:是。 1)如果这三个条件同时满足,则:“我一定要嫁给他!!!” 2)如果三个条件有为真的情况,则:“嫁吧,比上不足,比下有余。” 3)如果三个条件都不满足,则:“不嫁!”
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 import java.util.Scanner;class Exer2 { public static void main (String[] args) { Scanner scan = new Scanner (System.in); System.out.println("请输入你的身高(cm):" ); int height = scan.nextInt(); System.out.println("请输入你的财富(千万):" ); Double wealth = scan.nextDouble(); System.out.println("请输入你是否帅(是/否):" ); String isHandsome = scan.next(); if (height >= 180 && wealth >= 1 && isHandsome.equals("是" )){ System.out.println("我一定要嫁给他!!!" ); }else if (height >= 180 || wealth >= 1 || isHandsome.equals("是" )){ System.out.println("嫁吧,比上不足,比下有余" ); }else { System.out.println("不嫁!" ); } } }
switch-case
switch(表达式)中表达式的值必须是:byte,short,char,int,枚举 (jdk 5.0),String (jdk 7.0)
case子句中的值必须是常量,不能是变量名或不确定的表达式值
同一个switch语句,所有case子句中的常量值互不相同
break是可选的,break在执行完一个case分支后使程序跳出switch语句块,如果没有break,程序会顺序执行到switch结尾
default子句是可任选,位置也是灵活的,当没有匹配的case时,执行default
如果switch-case结构中的多个case的执行语句相同,则可以考虑进行合并
switch-case格式 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 switch (表达式){case 常量1 :语句1 ; case 常量2 :语句2 ; … … case 常量N:语句N; default :语句; }
练习 1.从键盘分别输入年、月、日,判断这一天是当年的第几天。 注:判断一年是否是闰年的标准: 1)可以被4整除,但不可被100整除 2)或可以被400整除
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 import java.util.Scanner;class Exer3 { public static void main (String[] args) { Scanner scan = new Scanner (System.in); System.out.println("请输入年:" ); int year = scan.nextInt(); System.out.println("请输入月:" ); int month = scan.nextInt(); System.out.println("请输入日:" ); int day = scan.nextInt(); int sumDay = 0 ; switch (month){ case 12 : sumDay += 30 ; case 11 : sumDay += 31 ; case 10 : sumDay += 30 ; case 9 : sumDay += 31 ; case 8 : sumDay += 31 ; case 7 : sumDay += 30 ; case 6 : sumDay += 31 ; case 5 : sumDay += 30 ; case 4 : sumDay += 31 ; case 3 : if ((year % 4 == 0 && year % 100 != 0 ) || year % 400 == 0 ){ sumDay += 29 ; }else { sumDay += 28 ; } case 2 : sumDay += 31 ; case 1 : sumDay += day; } System.out.println("这一天是当年的第 " + sumDay + " 天" ); } }
如果判断的具体数值不多,而且符合byte、short、char、int、String、枚举等几种类型,虽然if-else和switch-case都可以使用,但建议使用swtich语句,因为效率稍高。
对区间判断和结果为boolean类型判断优先选择if,if的使用范围更广。使用switch-case的,都可以改写为if-else。反之不成立。
2.中国的生肖基于12年一个周期,每年用一个动物代表,为一个给定的年份找出其对应的中国生肖。 注:2019年:猪 2019 % 12 == 3
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 import java.util.Scanner;class Exer4 { public static void main (String[] args) { Scanner scanner = new Scanner (System.in); System.out.println("请输入你的要查询的年份" ); int year = scanner.nextInt(); int shengXiao = year % 12 ; switch (shengXiao){ case 0 : System.out.println("猴年" ); break ; case 1 : System.out.println("鸡年" ); break ; case 2 : System.out.println("狗年" ); break ; case 3 : System.out.println("猪年" ); break ; case 4 : System.out.println("鼠年" ); break ; case 5 : System.out.println("牛年" ); break ; case 6 : System.out.println("虎年" ); break ; case 7 : System.out.println("兔年" ); break ; case 8 : System.out.println("龙年" ); break ; case 9 : System.out.println("蛇年" ); break ; case 10 : System.out.println("马年" ); break ; case 11 : System.out.println("羊年" ); break ; default : System.out.println("输入有错" ); } } }
循环结构 在某些条件满足的情况下反复执行特定代码,循环语句有for循环,while循环以及do-while循环。
for循环 for循环格式 1 2 3 for (①初始化部分;②循环条件部分;④迭代部分){ ③循环体部分; }
执行过程:① - ② - ③ - ④ - ② - ③ - ④ - ② - ③ - ④ -… - ② ①初始化部分可以声明多个变量,但必须是同一个类型,用逗号分隔 ②循环条件部分为boolean类型表达式,当值为false时,退出循环 ④可以有多个变量更新,用逗号分隔
练习 1.编写程序从1循环到150,并在每行打印一个值,另外在每个3的倍数行上打印出“foo”,在每个5的倍数行上打印“biz”,在每个7的倍数行上打印输出“baz”。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 class Exer5 { public static void main (String[] args) { for (int i = 1 ;i <= 150 ;i++){ System.out.print(i + " " ); if (i % 3 == 0 ){ System.out.print("foo " ); } if (i % 5 == 0 ){ System.out.print("biz " ); } if (i % 7 == 0 ){ System.out.print("baz " ); } System.out.println(); } } }
2.输入两个正整数m和n,求其最大公约数和最小公倍数。 比如:12和20的最大公约数是4,最小公倍数是60 说明:break关键字的使用
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 import java.util.Scanner;class Exer6 { public static void main (String[] args) { Scanner scan = new Scanner (System.in); System.out.println("请输入第一个整数:" ); int m = scan.nextInt(); System.out.println("请输入第二个整数:" ); int n = scan.nextInt(); int min = (m >= n)? n : m; for (int i = min;i >= 1 ;i-- ){ if (m % i == 0 && n % i == 0 ){ System.out.println("最大公约数是:" + i); break ; } } int max = (m >= n)? m : n; for (int i = max;i <= m * n;i++){ if (i % m == 0 && i % n == 0 ){ System.out.println("最大公倍数是:" + i); break ; } } } }
while循环 while循环格式 1 2 3 4 5 ①初始化部分 while (②循环条件部分){③循环体部分; ④迭代部分; }
执行过程:① - ② - ③ - ④ - ② - ③ - ④ - ② - ③ - ④ -… - ② 注意不要忘记声明④迭代部分,否则循环将不能结束,变成死循环 for循环和while循环: 1.for循环和while循环是可以相互转换的 2.for循环和while循环的区别是初始化条件部分的作用范围不同 3.开发中,基本上我们都会从for、while中进行选择,实现循环结构
练习 1 2 3 4 5 6 7 8 int result = 0 ;int i = 1 ;while (i <= 100 ) { result += i; i++; } System.out.println("result=" + result); System.out.println("i=" + i);
do-while循环 do-while循环格式 1 2 3 4 5 ①初始化部分; do {③循环体部分 ④迭代部分 }while (②循环条件部分);
执行过程:① - ③ - ④ - ② - ③ - ④ - ② - ③ - ④ -… - ② 1.do-while循环至少会执行一次循环体 2.开发中,使用for和while更多一些,较少使用do-while
练习 1 2 3 4 5 6 7 8 9 int number1 = 10 ;while (number1 > 10 ){ System.out.println("hello:while" ); number1--; int number2 = 10 ;do { System.out.println("hello:do-while" ); number2--; }while (number2 > 10 );
循环结构综合例题 从键盘读入个数不确定的整数,并判断读入的正数和负数的个数,输入为0时结束程序。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 import java.util.Scanner;class Exer7 { public static void main (String[] args) { Scanner scan = new Scanner (System.in); int positiveNumber = 0 ; int negativeNumber = 0 ; for (;;){ int number = scan.nextInt(); if (number > 0 ){ positiveNumber++; }else if (number < 0 ){ negativeNumber++; }else { break ; } } System.out.println("输入的正数个数为:" + positiveNumber); System.out.println("输入的负数个数为:" + negativeNumber); } }
最简单“无限” 循环格式:while(true)和for( ; ;) 无限循环存在的原因是并不知道循环多少次,需要根据循环体内部某些条件,来控制循环的结束 结束循环的方式:一是循环条件部分返回false;二是在循环体中,执行break
嵌套循环
将一个循环放在另一个循环体内就形成了嵌套循环,for,while,do…while均可作为外层或内层循环
实际上嵌套循环就是把内层循环当成外层循环的循环体。当只有内层循环的循环条件为false时,才会完全跳出内层循环,才可结束外层的当次循环,开始下一次的循环
设外层循环次数为m次,内层为n次,则内层循环体实际上需要执行m*n次
外层循环控制行数,内层循环控制列数
练习 1.九九乘法表
1 2 3 4 5 for (int i = 1 ;i <= 9 ;i++){ for (int j = 1 ;j <= i;j++){ System.out.print(i + " * " + j + " = " + (i * j) + " " ); } }
2.100000以内的所有质数
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 int count = 0 ;long start = System.currentTimeMillis();label:for (int i = 2 ;i <= 100000 ;i++){ for (int j = 2 ;j <= Math.sqrt(i);j++){ if (i % j == 0 ){ continue label; } } count++; } long end = System.currentTimeMillis();System.out.println("质数的个数为:" + count); System.out.println("所花费的时间为:" + (end - start));
“1”既不是质数,也不是合数。因为如果一个数不是质数是合数,那么一定可以由两个自然数相乘得到,其中一个大于或等于它的平方根,一个小于或等于它的平方根。并且成对出现,所以只用计算到该数的平方根以下看除了1有没有该数的因数,若没有,则是质数。
关键字break和continue的使用
break只能用于switch语句和循环语句中
continue 只能用于循环语句中
二者功能类似,但continue是终止本次循环,break是终止本层循环
break、continue之后不能有其他的语句,因为程序永远不会执行其后的语句
标号语句必须紧接在循环的头部。标号语句不能用在非循环语句的前面
很多语言都有goto语句,goto语句可以随意将控制转移到程序中的任意一条语句上,然后执行它,但容易使程序出错。Java中的break和continue是不同于goto的
1 2 3 4 5 6 7 for (int i = 1 ; i<= 10 ; i++){ if (i % 3 == 0 ){ break ; } System.out.print(i); }
1 2 3 4 5 6 for (int i = 1 ; i<= 10 ; i++){ if (i % 3 == 0 ){ continue ; } System.out.print(i); }
label标签的使用 break,continue语句出现在多层嵌套的语句块中时,可以通过标签指明要终止的是哪一层语句块
1 2 3 4 5 6 7 8 9 10 11 12 label:for (int i = 1 ;i <= 4 ;i++){ for (int j = 1 ;j <= 10 ;j++){ if (j % 4 == 0 ){ continue label; } System.out.print(j); } System.out.println(); }
return用法 return并非专门用于结束循环的,它的功能是结束一个方法。当一个方法执行到一个return语句时,这个方法将被结束。与break和continue不同的是,return直接结束整个方法,不管这个return处于多少层循环之内。