程序流程控制
流程控制语句是用来控制程序中各语句执行顺序的语句,可以把语句组合成能完成一定功能的小逻辑模块。流程控制方式采用结构化程序设计中规定的三种基本流程结构,即顺序结构,分支结构和循环结构。
- 顺序结构:程序从上到下逐行地执行,中间没有任何判断和跳转
- 分支结构:根据条件选择性地执行某段代码,有if…else和switch-case两种分支语句
- 循环结构:根据循环条件,重复性的执行某段代码,有while、do…while、for三种循环语句,JDK1.5提供了foreach循环,方便的遍历集合、数组元素
分支结构
if-else
- 条件表达式必须是布尔表达式(关系表达式或逻辑表达式)、布尔变量
- 语句块只有一条执行语句时,一对{}可以省略,但建议保留
- 当if-else结构是“多选一”时,最后的else是可选的,根据需要可以省略
- 当多个条件是“互斥”关系时,条件判断语句及执行语句间顺序无所谓
- 当多个条件是“包含”关系时,“小上大下 / 子上父下”
- if-else语句结构,根据需要可以嵌套使用
if语句的三种格式
//格式一
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)如果用户输入的数字没有匹配任何一个数字,则彩票作废
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)如果三个条件都不满足,则:“不嫁!”
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格式
switch(表达式){
case 常量1:
语句1;
// break;
case 常量2:
语句2;
// break;
… …
case 常量N:
语句N;
// break;
default:
语句;
// break;
}
练习
1.从键盘分别输入年、月、日,判断这一天是当年的第几天。
注:判断一年是否是闰年的标准:
1)可以被4整除,但不可被100整除
2)或可以被400整除
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
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循环格式
for(①初始化部分;②循环条件部分;④迭代部分){
③循环体部分;
}
执行过程:① - ② - ③ - ④ - ② - ③ - ④ - ② - ③ - ④ -… - ②
①初始化部分可以声明多个变量,但必须是同一个类型,用逗号分隔
②循环条件部分为boolean类型表达式,当值为false时,退出循环
④可以有多个变量更新,用逗号分隔
练习
1.编写程序从1循环到150,并在每行打印一个值,另外在每个3的倍数行上打印出“foo”,在每个5的倍数行上打印“biz”,在每个7的倍数行上打印输出“baz”。
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关键字的使用
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;//一旦在循环中执行到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;//一旦在循环中执行到break,就跳出循环
}
}
}
}
while循环
while循环格式
①初始化部分
while(②循环条件部分){
③循环体部分;
④迭代部分;
}
执行过程:① - ② - ③ - ④ - ② - ③ - ④ - ② - ③ - ④ -… - ②
注意不要忘记声明④迭代部分,否则循环将不能结束,变成死循环
for循环和while循环:
1.for循环和while循环是可以相互转换的
2.for循环和while循环的区别是初始化条件部分的作用范围不同
3.开发中,基本上我们都会从for、while中进行选择,实现循环结构
练习
int result = 0;
int i = 1;
while (i <= 100) {
result += i;
i++;
}
System.out.println("result=" + result);//1 + 2 +3 + ... + 100 = 5050
System.out.println("i=" + i);//101;出了while循环以后,仍可以调用,for循环不可以
do-while循环
do-while循环格式
①初始化部分;
do{
③循环体部分
④迭代部分
}while(②循环条件部分);
执行过程:① - ③ - ④ - ② - ③ - ④ - ② - ③ - ④ -… - ②
1.do-while循环至少会执行一次循环体
2.开发中,使用for和while更多一些,较少使用do-while
练习
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时结束程序。
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(;;){ //while(true){
int number = scan.nextInt();
//判断number的正负情况
if(number > 0){
positiveNumber++;
}else if(number < 0){
negativeNumber++;
}else{
break;//一旦执行break,跳出循环
}
}
System.out.println("输入的正数个数为:" + positiveNumber);
System.out.println("输入的负数个数为:" + negativeNumber);
}
}
最简单“无限” 循环格式:while(true)和for( ; 😉
无限循环存在的原因是并不知道循环多少次,需要根据循环体内部某些条件,来控制循环的结束
结束循环的方式:一是循环条件部分返回false;二是在循环体中,执行break
嵌套循环
- 将一个循环放在另一个循环体内就形成了嵌套循环,for,while,do…while均可作为外层或内层循环
- 实际上嵌套循环就是把内层循环当成外层循环的循环体。当只有内层循环的循环条件为false时,才会完全跳出内层循环,才可结束外层的当次循环,开始下一次的循环
- 设外层循环次数为m次,内层为n次,则内层循环体实际上需要执行m*n次
- 外层循环控制行数,内层循环控制列数
练习
1.九九乘法表
for(int i = 1;i <= 9;i++){
for(int j = 1;j <= i;j++){
System.out.print(i + " * " + j + " = " + (i * j) + " ");
}
}
2.100以内的所有质数
int count = 0;//记录质数的个数
long start = System.currentTimeMillis();//获取当前时间距离1970-01-01 00:00:00 的毫秒数
label:for(int i = 2;i <= 100000;i++){//遍历100000以内的自然数
for(int j = 2;j <= Math.sqrt(i);j++){//j:被i去除;sqrt优化二
if(i % j == 0){ //i被j除尽
continue label;//优化一
}
}
//能执行到此步骤的,都是质数
count++;
}
long end = System.currentTimeMillis();//获取当前时间距离1970-01-01 00:00:00 的毫秒数
System.out.println("质数的个数为:" + count);
System.out.println("所花费的时间为:" + (end - start));
//未优化:17110 - 优化一:continue:1546 - 优化二:13
关键字break和continue的使用
- break只能用于switch语句和循环语句中
- continue 只能用于循环语句中
- 二者功能类似,但continue是终止本次循环,break是终止本层循环
- break、continue之后不能有其他的语句,因为程序永远不会执行其后的语句
- 标号语句必须紧接在循环的头部。标号语句不能用在非循环语句的前面
- 很多语言都有goto语句,goto语句可以随意将控制转移到程序中的任意一条语句上,然后执行它,但容易使程序出错。Java中的break和continue是不同于goto的
- break用法举例
for(int i = 1; i<= 10; i++){
if(i % 3 == 0){
break;
//System.out.println("今晚迪丽热巴要约我!!!");//关键字后面不能声明执行语句
}
System.out.print(i);//12
}
- continue用法举例
for(int i = 1; i<= 10; i++){
if(i % 3 == 0){
continue;
}
System.out.print(i);//12457810
}
- label标签的使用
break,continue语句出现在多层嵌套的语句块中时,可以通过标签指明要终止的是哪一层语句块
label:for(int i = 1;i <= 4;i++){
for(int j = 1;j <= 10;j++){
if(j % 4 == 0){
//break;//默认跳出包裹此关键字最近的一层循环。
//continue;
//break label;//结束指定标识的一层循环结构//123
continue label;//结束指定标识的一层循环结构当次循环//123123123123
}
System.out.print(j);
}
System.out.println();
}
- return用法
return并非专门用于结束循环的,它的功能是结束一个方法。当一个方法执行到一个return语句时,这个方法将被结束。与break和continue不同的是,return直接结束整个方法,不管这个return处于多少层循环之内。
本文作者: susin3x
本文链接: https://susin3x.cn/posts/aeb4efef.html
版权声明: 本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!