Java流程控制详解

  • Post author:
  • Post category:java

一、流程控制概述

        在Java程序中,JVM默认总是顺序执行以分号;结束的语句。但是,在实际的代码中,程序经常需要做条件判断、循环,因此,需要有多种流程控制语句,来实现程序的跳转和循环等功能。

        流程控制语句是用来控制程序中各语句执行顺序的语句,可以把语句组合成能完成一定功能的小逻辑模块。
    
        其流程控制方式采用结构化程序设计中规定的三种基本流程结构,即:
                顺序结构
                分支结构
                循环结构

 二、顺序结构

        顺序结构是程序中最简单最基本的流程控制,没有特定的语法结构,按照代码的先后顺序,依次执行,程序中大多数的代码都是这样执行的。

        总的来说:程序按照从上到下的顺序执行。

 Java顺序结构示例代码:

public class Order {
    public static void main(String[] args) {
        System.out.println(1);
        System.out.println(2);
        System.out.println(3);
    }
}

三、分支结构

        根据条件,选择性地执行某段代码。

        有if…else和switch-case两种分支语句。

3.1 if单分支语句

语法:
        if(条件表达式){
                语句块;
        }
解释:
        条件表达式结果为boolean类型,当表达式结果为true,则执行语句块;否则什么都不执行!
        当语句块只有一条执行语句时,一对{}可以省略,但建议保留。

 Java if单分支示例代码:

public class IfTest {
    public static void main(String[] args) {
        int a = 10;
        int b = 10;

        if(a > b){
            System.out.println("a 大于 b");
        }

        System.out.println("-------------");

        if(a==b){
            System.out.println("a 等于 b");
        }
   }
}

练习题:

        张浩Java成绩大于98分,而且音乐成绩大于80分,老师奖励他;或者Java成绩等于100分,音乐成绩大于70分,老师也可以奖励他.

public class Prize {
    public static void main(String[] args) {
        int score1 = 100; // 张浩的Java成绩
        int score2 = 72; // 张浩的音乐成绩
        if ( ( score1 >98&& score2 > 80 )|| ( score1 == 100 && score2 > 70 ) ){
            System.out.println("老师说:不错,奖励一个MP4!");
        }
    }
}

3.2 if双分支语句

语法:
        if(条件表达式){
                语句块A;
        }else{
                语句块B;
        }
解释:
        条件表达式结果为boolean类型,当表达式结果为true,则执行语句块A;否则执行语句块B。
        if-else语句结构,根据需要可以嵌套使用。

public class IfDemo {
    public static void main(String[] args) {
        int a = 10;
        int b = 10;

        if(a == b){
            System.out.println("a 等于 b");
        }else{
            System.out.println("a 不等于 b");
        }

        System.out.println("---------------");

        if(a > b){
            System.out.println("a 大于 b");
        }else{
            System.out.println("a 不大于 b");
        }
        
        System.out.println("---------------");
        int age = 3;
        if(age >= 3 && age < 6){
            System.out.println("符合入园年龄,可以报名。");
        }else{
            System.out.println("赶紧去上小学把。");
        }
        
   }
}

练习题:

        如果张浩Java考试成绩大于98分,老师就奖励他一个MP4,否则老师就罚他进行编码。

public class SimpleIf {
	public static void main(String[] args) {
		int score = 91; // 张浩的Java成绩
		if (score > 98) {
			System.out.println("老师说:不错,奖励一个MP4!");
		} else {
			System.out.println("老师说:惩罚进行编码!");
		}
	}
}

3.3 if多分支语句

语法:
        if(条件表达式A){
                语句块A;
        }else if(条件表达式B){
                语句块B;
        }…
        else if(条件表达式N){
                语句块N;
        }else{
                语句块N+1
        }
解释:
        所有的条件表达式结果都是boolean类型。
        如果条件表达式A结果为true,则执行语句块A,否则去判断条件表达式B;
        如果条件表达式B结果为true,则执行语句块B,否则去判断条件表达式C;
        ….
        如果所有的条件表达式结果都为false,则执行语句块N+1
        else是可选的,根据需要可以省略

        注:
                当多个条件是“互斥”关系(没有交集)时,条件判断语句及执行语句间顺序无所谓
                当多个条件是“非互斥”关系(有交集)时,需要根据实际情况,考虑如何定义顺序。
                当多个条件是“包含”关系时,“小上大下 / 子上父下”

为什么使用多重if选择结构?

问题:对学员的结业考试成绩评测
        成绩大于等于90时,评估结果为:优秀
        成绩为(80-89)时,评估结果为:良好    
        成绩为(60-79)时,评估结果为:中等
        成绩小于60时,评估结果为:差

分析:将成绩分成几个连续区间判断。使用单个if选择结构无法完成,使用多个if选择结构很麻烦 ,所以要使用多重if选择结构。

int score = 70;    //考试成绩

if ( score >= 90 ) {    
    System.out.println("优秀");
} else if (score >= 80 ) {    
    System.out.println("良好");
} else if (score >= 60 ) {    
    System.out.println("中等");
} else {    
    System.out.println("差");
}

练习题:

我想买车,买什么车决定于我在银行有多少存款
        如果我的存款超过500万,我就买凯迪拉克
        否则,如果我的存款超过100万,我就买帕萨特
        否则,如果我的存款超过50万,我就买依兰特
        否则,如果我的存款超过10万,我就买奥托
        否则,我买捷安特

请从键盘输入我的存款,并加以判断
        需要Scanner类
        1、导包,Scanner类在java.util.Scanner包下
        2、实例化Scanner对象
        3、调用Scanner类相关API,获取相应类型的变量
        注:如果输入类型不匹配,会抛出异常!

// 扫描器类
Scanner input = new Scanner(System.in);
// 输入int类型的值
int money = input.nextInt(); // 我的存款,单位:万元
// 判断
if (money >= 500) {
    System.out.println("太好了,我可以买凯迪拉克");
} else if (money >= 100) {
    System.out.println("不错,我可以买辆帕萨特");
} else if (money >= 50) {
    System.out.println("我可以买辆依兰特");
} else if (money >= 10) {
    System.out.println("至少我可以买个奥托");
} else {
    System.out.println("看来,我只能买个捷安特了");
}

练习题:

        定义三个int型变量并赋值,使用三元运算符或者if-else获取这三个数中的较大数的实现

// 声明三个变量并赋值
int num1 = 10,num2 = 20,num3 = -5;

// 声明max变量,根据判断赋值
int max;
if(num1 >= num2 && num1 >= num3){
    max = num1;
}else if(num2 >= num1 && num2 >= num3){
    max = num2;
}else{
    max = num3;
}

练习题:

        编写一个程序,获取用户输入的狗的年龄,通过程序显示其相当于人类的年龄。如果用户输入负数,请显示一个提示信息。
        算法:狗的前两年每一年相当于人类的10.5岁,之后每增加一年就增加四岁。

int dogAge = 7;
if(dogAge >= 0 && dogAge <= 2){
    System.out.println("相当于人的年龄:" + dogAge * 10.5);
}else if( dogAge > 2){
    System.out.println("相当于人的年龄:" + (2 * 10.5 + (dogAge - 2) * 4));
}else{
    System.out.println("狗狗还没出生呢!");
}

3.4 嵌套if

为什么使用嵌套if?

问题:学校举行运动会,百米赛跑跑入10秒内的学生有资格进决赛,根据性别分别进入男子组和女子组。

分析:
        要判断是否能够进入决赛。
        在确定进入决赛的情况下,还要判断是进入男子组,还是进入女子组。
    
解决:
        使用嵌套if选择结构

语法参考: 
if(条件1) {
        if(条件2) {
              代码块1
        } else {
              代码块2
        }
} else {
        代码块3
}

if(score <= 10){
    if(gender.equals("男")){
        System.out.println("进入男子组决赛!");
    }else if(gender.equals("女")){
        System.out.println("进入女子组决赛!");
    }
}else{
    System.out.println("淘汰!");
}

        为了使 if 结构更加清晰、避免执行错误,应该把每个 if 或 else 包含的代码块都用大括号括起来;
        相匹配的一对 if 和 else 应该左对齐;
        内层的 if 结构相对于外层的 if 结构要有一定的缩进;

3.5 switch语句

语法:
        switch(表达式){
                case 值1:
                        语句块1;
                        break;
                …..
                case 值N:
                        语句块N;
                        break;
                default: 
                        语句块default;
    }        
解释:
        根据switch表达式中的值,依次匹配各个case中的常量。一旦匹配成功,则进入相应case结构中,调用其执行语句。当调用完执行语句以后,则仍然继续向下执行其他case结构中的执行语句,直到遇到break关键字或switch-case结构末尾结束为止。
        表达式在这里其实是一个值:但是必须是byte,short,int,char,枚举类型(JDK5.0新增)、String(JDK7.0新增)其中的一种。
        break不是语法中固定的,可以加也可以不加,但是如果为了打断switch的贯穿性,需要结合break使用。
        default块顺序可以变动,但要注意其执行顺序。通常,default块放在末尾,也可以省略;但是如果default放在前面,推荐添加break;
        case的顺序无所谓,case 之后只能声明常量,不能声明范围。
        程序会使用表达式值从上到下跟case后面的值进行比较,如果相等,则执行对应的语句块,否则继续向后对比;
        如果都不相等,则执行default。

import java.util.Scanner;

public class SwitchDemo {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        System.out.println("只能输入1,2,3:");
        int a = sc.nextInt();
        switch(a){
            case 1:
                System.out.println("one");
                break;
            case 2:
                System.out.println("two");
                break;

            case 3:
                System.out.println("three");
                break;
            default:
                System.out.println("输入错误,请重新输入");
        }
    }
}

练习题:

韩嫣参加计算机编程大赛
        如果获得第一名,将参加麻省理工大学组织的1个月夏令营
        如果获得第二名,将奖励惠普笔记本电脑一部
        如果获得第三名,将奖励移动硬盘一个
        否则,不给任何奖励
该问题属于等值判断,解决方法:
        使用多重if选择结构实现
        使用switch选择结构解决

int mingCi = 1;
switch (mingCi) {
    case 1:
        System.out.println("参加麻省理工大学组织的1个月夏令营");
        break;
    case 2:
        System.out.println("奖励惠普笔记本电脑一部");
        break;
    case 3:
        System.out.println("奖励移动硬盘一个");
        break;
    default:
        System.out.println("没有任何奖励 ");
}

下列语句的执行结果

 int mingCi = 1;
 switch (mingCi){
	    case 1:
                System.out.println("参加麻省理工大学组织的1个月夏令营");               
        case 2:
                System.out.println("奖励惠普笔记本电脑一部");                
        case 3:
                System.out.println("奖励移动硬盘一个");                
        default:
                System.out.println("没有任何奖励 ");
 }
//如果需要每个case执行完后跳出,在每个case后不要忘记写break;

练习题:

        对学生成绩大于60分的,输出“合格”。低于60分的,输出“不合格”。
        注:switch-case结构来实现;

int score = 78;
switch(score / 10){
    case 0:
    case 1:
    case 2:
    case 3:
    case 4:
    case 5:
        System.out.println("不及格");
        break;
    case 6:
    case 7:
    case 8:
    case 9:
    case 10:
        System.out.println("及格");
        break;
}

//更优的解决方案:
switch(score / 60){
    case 0:
        System.out.println("不及格");
        break;
    case 1:
        System.out.println("及格");
        break;
}

3.6 比较switch和多重if选择结构

相同点
        都是用来处理多分支条件的结构
不同点
        switch选择结构:只能处理等值条件判断的情况,而且条件必须是整型变量或字符型变量
        多重if选择结构:没有switch选择结构的限制,特别适合某个变量处于某个连续区间时的情况
        if 在应用中更为常见,有时switch 结构更清晰.    
注:凡是可以使用switch-case的结构,都可以使用if-else;反之不成立。

四、循环结构

        在某些条件满足的情况下,反复执行特定代码的功能
        有while、do…while、for三种循环语句。
        注:JDK1.5提供了foreach循环,方便的遍历集合、数组元素。

4.1 循环分类

        顺序结构或分支结构的程序语句只能 被执行一次。如果你要同样的操作执行多次,就需要使用循环结构。

         执行一些需要重复的操作时,要用到循环流程.
        在现实与程序中会大量的用到循环流程 .

设想:

小明为了表示对JAVA的喜欢,想要写100句 “ JAVA我爱你! ”
        1遍: System.out.println(“JAVA我爱你!”);
        2遍: System.out.println(“JAVA我爱你!”);
        … …
        100遍: System.out.println(“JAVA我爱你!”);

如果是1万遍呢?
        1遍: System.out.println(“JAVA我爱你!”);
        2遍: System.out.println(“JAVA我爱你!”);
        ….
        7777遍… …
        小明工作了一天,累成狗,老板还不满意他的工作…

循环语句分类

while循环
do-while循环
for循环
        单层for循环
        双层for循环
        增强for循环(foreach)
        嵌套循环

循环语句的四个组成部分

初始化部分(init_statement)
循环条件部分(test_exp)
循环体部分(body_statement)
迭代部分(alter_statement)

4.2 while循环

语法:
        ①初始化部分
        while(②循环条件部分){
                ③循环体部分; 
                ④迭代部分; 
        }

执行过程:
        ①-②-③-④-②-③-④-②-③-④-…-②

解释:
        条件表达式返回值类型为boolean类型,只要条件表达式的结果为true,则一直执行语句块。

特点:先判断,再执行

注:
        不要忘记声明④迭代部分。否则,循环将不能结束,变成死循环。
        for循环和while循环可以相互转换,区别点:for循环和while循环的初始化变量作用域不同。

public class WhileLoop {
    public static void main(String[] args) {
        int sum = 0;
        int i = 1;
        while(i <= 10){
            sum += i;
            i++;
        }
        System.out.println("sum:"+sum);
    }
}

练习题:

问题:如何用程序描述下面这个故事呢?
        为了帮助张浩尽快提高成绩,老师给他安排了每天的学习任务,
        其中上午阅读教材,学习理论部分,下午上机编程,掌握代码部分。
        老师每天检查学习成果。如果不合格,则继续进行
分析:使用while循环的步骤
        1、分析循环条件和循环操作
        2、套用while语法写出代码
        3、检查循环是否能够退出

System.out.print("合格了吗?(y/n):");
String answer = input.next();
while(answer.equals("y") == false){
    System.out.println("上午阅读教材!");
    System.out.println("下午上机编程!\n");
    System.out.print("合格了吗?(y/n):");
    answer = input.next();
}
System.out.println("完成学习任务!");

4.3 do…while循环

语法:
        ①初始化部分;
        do{
                ③循环体部分
                ④迭代部分
        }while(②循环条件部分);

执行过程:
        ①-③-④-②-③-④-②-③-④-…②

解释:
        先执行do对应的语句块,然后再判断循环条件,只要循环条件满足,则一直执行循环体,否则结束循环。
特点:先执行,再判断;do-while循环至少执行一次循环体。

public class DoWhileLoop {
    public static void main(String[] args) {
        int sum = 0;
        int i = 1;
        do{
            sum+=i;
            i++;
        }while(i<=10);
        System.out.println("sum:"+sum);
    }
}

为什么需要do-while循环?

经过几天的学习,老师给张浩一道测试题,
让他先上机编写程序完成,
然后老师检查是否合格。如果不合格,则继续编写。……

do{
    System.out.println("上机编写程序!");
    System.out.print("合格了吗?(y/n)");
    answer = input.next();
    System.out.println("");
}while(!"y".equals(answer));

System.out.println("恭喜你通过了测试!");

while和do while的区别?

执行次序不同:
        while先判断,再执行;do while先执行,再判断
初始情况不满足循环条件时:
        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);

4.4 for循环

语法:
        for( ①初始化循环条件; ②循环条件表达式 ; ④迭代部分 ){
                ③循环操作(循环体);
        }

执行过程:
        ①-②-③-④-②-③-④-②-③-④-…..-②

解释:
        1、先执行初始化循环条件
        2、使用初始表达式值进行条件判断,如果判断为true,则执行循环操作;否则结束循环
        3、进行迭代
        4、循环迭代可以在()里面省略,在循环体里面进行迭代也可。

 练习题:

循环输入某同学结业考试的5门课成绩,并计算平均分
        1、分析循环条件和循环操作
        2、套用for语法写出代码
        3、检查循环是否能够退出

// 定义sum,用来存储叠加求和
int sum = 0;         
// 循环5次录入5门课成绩
for(int i = 0; i < 5; i++){  	
    System.out.print("请输入5门功课中第" + (i+1) + "门课的成绩: ");
    score = input.nextInt();  	//录入成绩
    sum = sum + score;        	//计算成绩和
}
// 计算平均分
avg = sum / 5;                      
System.out.println(name + "的平均分是:" + avg);

三种循环对比:

执行顺序
        先判断,后执行: while 和 for
        先执行,后判定: do-while    
适用
        循环次数确定: 一般使用for
        循环次数不确定: 一般使用while 和 do-while

4.5 循环嵌套

        将一个循环放在另一个循环体内,就形成了嵌套循环。其中,for ,while ,do…while均可以作为外层循环或内层循环。

        实质上,嵌套循环就是把内层循环当成外层循环的循环体。当只有内层循环的循环条件为false时,才会完全跳出内层循环,才可结束外层的当次循环,开始下一次的循环。

        设外层循环次数为m次,内层为n次,则内层循环体实际上需要执行m*n次。

// 打印五颗星 *****
// System.out.println("*****");
for (int i = 1; i <= 5; i++) {
    System.out.print('*');
}
System.out.println("\n");

/*
	打印五次五颗星,如果定义五次上述代码,显然不太好;
	那么就把上述代码,再放到一个循环结构中,就是嵌套循环
	*****
	*****
	*****
	*****
	*****
*/
for (int j = 1; j <= 5; j++) {
    for (int i = 1; i <= 5; i++) {
        System.out.print('*');
    }
    System.out.println();
}

打印直角三角形:

/*			i(行号)		j(*的个数)
	*			1			1
	**			2			2
	***			3			3
	****		4			4
	*****		5			5
*/
for (int i = 1; i <= 5; i++) {//控制行数
    for (int j = 1; j <= i; j++) {//控制列数
        System.out.print("*");

    }
    System.out.println();
}

打印倒直角三角形:

/*			i(行号)		j(*的个数)   规律:i + j = 5 换句话说:j = 5 - i;
	****		1			4
	***			2			3
	**			3			2
	*			4			1
*/
for (int i = 1; i <= 4; i++) {
    for (int j = 1; j <= 5 - i; j++) {
        System.out.print("*");
    }
    System.out.println();
}

打印等腰三角形

/*
	1	    *			4个空格
	2	   ***			3个空格
	3	  *****			2个空格
	4	 *******		1个空格
	5	*********
*/
for (int i = 1; i <= 5; i++) {
    for (int j = 5; j >= i; j--) {
        System.out.print(" ");
    }
    for (int j = 1; j <= i * 2 - 1; j++) {
        System.out.print("*");
    }
    System.out.println();
}

总结规律:
        第一个(外层)for循环作用:控制行数

        第二个(内层)for循环作用:控制列数

五、流程跳转

break        用于do-while、while、for、switch中时,可跳出循环而执行循环后面的语句
continue    用在循环中,跳过本次循环,执行下一次循环.

5.1 break

语法:
        循环(…) {
                ……
                break;
                ……
        }

解释:
        break语句用于终止某个语句块的执行
        break通常在循环中与条件语句一起使用

public class BreakTest {
    public static void main(String args[]) {
        for (int i = 0; i < 10; i++) {
            if (i == 3)
                break;
            System.out.println(" i = " + i);
        }
    }
}

练习题:

问题:循环录入某学生5门课的成绩并计算平均分,如果某分数录入为负,停止录入并提示录入错误
分析:循环录入成绩,判断录入正确性:录入错误,使用break语句立刻跳出循环;否则,累加求和

public class BreakTest {
    public static void main(String args[]) {
        Scanner input = new Scanner(System.in);
        // 记录总分
        int sum = 0;
        // 循环5次录入5门课成绩
        for (int i = 0; i < 5; i++) {
            System.out.print("请输入第" + (i + 1) + "门课的成绩: ");
            int score = input.nextInt();
            // 输入负数
            if (score < 0) {
                break;
            }
            // 累加求和
            sum = sum + score;
        }
        System.out.println("学生5门课的平均分是:" + sum / 5);
    }
}

5.2 continue

语法:
        循环(…){
                ….
                continue;
                ….
        }

解释:
        continue只能使用在循环结构中
        continue语句用于跳过其所在循环语句块的一次执行,继续下一次循环
        continue语句出现在多层嵌套的循环语句体中时,可以通过标签指明要跳过的是哪一层循环

public class ContinueTest {
    public static void main(String args[]) {
        for (int i = 0; i < 10; i++) {
            if (i == 3)
                continue;
            System.out.println(" i = " + i);
        }
    }
}

练习题:

循环录入Java课的学生成绩,统计分数大于等于80分的学生比例 
        1、通过循环,获得分数大于等于80分的学生人数num
        2、判断:如果成绩<80,不执行num++,直接进入下一次循环

public class ContinueTest {
    public static void main(String args[]) {
        Scanner input = new Scanner(System.in);
        System.out.print("输入班级总人数:");
        int total = input.nextInt();
        // 统计80分以上学生数量
        int num = 0;
        // 循环输入学生成绩
        for (int i = 0; i < total; i++) {
            System.out.print("请输入第" + (i + 1) + "位学生的成绩: ");
            int score = input.nextInt();
            if (score < 80) {
                continue;
            }
            num++;
        }
        System.out.println("80分以上的学生人数是: " + num);
        double rate = (double) num / total * 100;
        System.out.println("80分以上的学生所占的比例为:" + rate + "%");
    }
}

5.3 多层循环跳转

        嵌套循环时: 内循环可以使用外循环中的变量,外循环每循环一次,内循环都会重新循环,并循环完内循环的所有次。
        break/continue 只会控制当前的循环,可以使用给循环设定标签的形式来控制循环.

label1: { ……
        label2: { ……
                label3: { ……
                        break label2;
                ……
                } 
        } 
}

5.4 return

        return:并非专门用于结束循环的,它的功能是结束一个方法。当一个方法执行到一个return语句时,这个方法将被结束。

     与break和continue不同的是,return直接结束整个方法,不管这个return处于多少层循环之内。

public class ReturnTest {
    public static void main(String args[]) {
        for (int i = 1; i <= 10; i++) {
            for (int j = 1; j <= 10; j++) {
                if (i + j == 15) {
                    return;
                }
                System.out.println("i = " + i + ",j = " + j + ",i + j = " + (i + j));
            }
        }

        System.out.println("循环之后的语句");
    }
}

5.5 三者对比

break和continue对比:

使用场合不同
        break可用于switch结构和循环结构中。
        continue只能用于循环结构中。

作用不同(循环结构中)
        break语句终止某个循环,程序跳转到循环块外的下一条语句。
        continue跳出本次循环,进入下一次循环。

注:很多语言都有goto语句,goto语句可以随意将控制转移到程序中的任意一条语句上,然后执行它。但使程序容易出错。Java中的break和continue是不同于goto的

continue、break、return三者对比:

continue:
    跳过本次循环,继续下一次循环
break:
    结束所在的循环。
return:
    结束整个方法    


版权声明:本文为ligonglanyuan原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。