• 第三章 流程控制语句结构


    第三章 流程控制语句结构

    写程序的最终目的是为了解决日常生活和工作中的问题。日常生活和工作中做的事情和解决方法,需要有一定的步骤和流程。Java使用顺序结构、分支结构、循环结构,将多个语句组合在一起,以便实现和控制任务的执行流程。

    3.1 顺序结构

    顺序结构是所有流程控制语句结构中最基础的结构,顺序结构的程序从整体来看都是顺序执行的。

    3.1.1 顺序结构的特点

    Java中的顺序结构指语句按照从上到下的编写顺序依次执行。

    3.1.2 输出语句

    System.out.println("内容") //输出之后换行
    System.out.print("内容"); //输出内容之后不换行
    
    • 1
    • 2

    无论是哪一种输出语句,括号中都只能有一个值,要么是一个常量值,要么是一个变量值,要么是一个表达式的计算结果。如果有多个值,那么应考虑使用运算符"+"将它们连接起来。

    3.1.3输入语句

    在程序运行期间间接接收从控制台输入的数据。使用util包中的Scanner类,示例如下:

    import java.util.Scanner; // 导包
    public class TestInput{
    	public static void main(String[] args){
    		Scanner input = new Scanner(System.in); // 使用Scanner类声明一个变量input
    		
    		System.out.println("请输入一个整数:");
    		int num = input.nextInt(); // 接受输入一个int值,并且把值存放在变量num变量。
    		System.out.println("num =" + num);
    	}
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    如果输入的是小数会报错,因为输入语句只接受int值,因为Java是强语言类型。如果要接收其他类型的数据,通常使用一下几种数据类型的接收方式:

    • Scanner类型的变量.nextByte():用于接收一个byte值;
    • Scanner类型的变量.nextShort():用于接收一个short值;
    • Scanner类型的变量.nextInt():用于接收一个int值;
    • Scanner类型的变量.nextLong():用于接收一个long值;
    • Scanner类型的变量.nextFloat():用于接收一个float值;
    • Scanner类型的变量.nextDouble():用于接收一个double值;
    • Scanner类型的变量.nextBoolean():用于接收一个boolean值;
    • Scanner类型的变量.next():用于接收一个String字符串;
    • Scanner类型的变量.next().charAt(0):用于接收一个char值。

    示例:

    import java.util.Scanner;
    
    public class InputInfoDemo{
    	public static void main(String[] args){
    		Scanner input = new Scanner(System.in);
    		
    		System.out.print("请输入姓名:");
    		String name = input.next();
    		
    		System.out.print("请输入年龄:");
    		int age = input.nextInt();
    		
    		System.out.print("请输入体重:");
    		double weight = input.nextDouble();
    		
    		System.out.print("请输入婚否:");
    		boolean marry = input.nextBoolean();
    		
    		System.out.print("请输入性别:");
    		char gender = input.next().charAt(0);
    		
    		System.out.println("姓名:" + name);
    		System.out.println("年龄:" + age + "岁");
    		System.out.println("体重:" + weight + "斤");
    		System.out.println("婚否:" + (marry ? "已婚":"未婚"));
    		System.out.println("性别:" + gender);
    	}
    }
    
    • 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

    3.2 分支结构if-else

    在实际生活中经常需要做出一些判断,比如开车来到一个十字路口,就需要对红绿灯进行判断,如果前面是红灯,就停车等候,如果是绿灯,就通行。Java中有一种特殊的语句叫做选择语句,它也需要对一些条件做出判断,从而决定执行哪一段代码。分支结构是指程序中出现了多种选择,即某些语句可能执行,可能不执行,是否执行要看条件是否满足。Java中的分支结构有两种:if系列的条件判断和switch系列的选择机构。
    if系列的条件判断是通过布尔型的表达式或值进行条件判断的,最终选择执行一条路径,根据供选择路径的数量不同,if系列的条件判断可分为三种形式,即单分支、双分支和多分支。

    3.2.1 单分支条件判断if

    程序只有一个分支可选,条件成立就执行该对应的语句,不成立则不执行,如下图所示:

    单分支条件判断if的语法如下:

    if (条件表达式){
    代码块
    }

    如果条件表达式成立(结果为true),则执行大括号中的语句块;如果不成立(结果为false),则跳过大括号中的语句块,直接执行语句块下的其他语句。
    条件表达式的结果只能是布尔类型,支持以下几种形式:

    布尔型的变量;
    布尔型的常量;
    布尔型的表达式,如关系表达式、逻辑表达式。

    语句块可以有零条或多条语句组成,如果里面仅有一条,则可以省略大括号,示例:

    if (a>b)
    System.out.println("a>b")
    
    • 1
    • 2

    注意:
    如果语句块由多条语句组成,则不能省略大括号
    示例:

    public class Example07 {
    	public static void main(String[] args) {
    		int x = 5;
    		if (x < 10) {
    			x++;
    		}
    		System.out.println("x=" + x);
    	}
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    案例:2月份的总天数,用键盘输入一个年份值,输出该年2月份的总天数

    import java.util.Scanner;
    
    public class DaysOfFebruaryDemo{
        public static void main(String[] args){
            int dayOfFebruary = 28;
            Scanner input = new Scanner(System.in);
            
            System.out.print("请输入年份:");
            int year = input.nextInt();
            
            if ((year % 4 == 0 && year % 100 !=0) || year % 400 ==0) {
                dayOfFebruary++;
            
            }
            System.out.println(year + "年的2月份有" +  dayOfFebruary + "天");
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17

    3.2.2 双分支条件判断 if … else

    双分支条件判断是在if判断的基础上增加与if判断条件表达式相反的代码执行块,这样就可以完成true、false的双向判断,并执行相应的代码执行块。
    流程图如下所示:

    双分支条件判断 if … else 语法如下:

    if (条件表达式) {
    语句块1;
    } else {
    语句块2;
    }

    可以发现两个if的条件是"非此即彼"的关系,此时可以使用一个承上启下的关键词"else",代表"否则",用于连接if条件不满足的情况下要执行的语句。
    如果条件表达式成立(结果为true),则执行语句块1;如果条件表达式不成立(结果为false),则执行语句块2。

    注意事项:

    1. 条件表达式必须是布尔表达式(关系表达式或逻辑表达式)、布尔变量或常量。
    2. 当语句块只有一条执行语句时,可以省略大括号,但建议保留。

    案例:用键盘输入一个年份,判断是闰年还是平年。

    import java.util.Scanner;
    
    public class LeapYear{
        public static void main(String[] args){
            Scanner input = new Scanner(System.in);
            
            System.out.print("请输入年份:");
            int year = input.nextInt();
            
            if ((year % 4 == 0 && year % 100 !=0) || year % 400 ==0){
                System.out.println(year + "是闰年");
            } else {
                System.out.println(year + "是平年");
            }
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

    3.2.3 多分支条件判断 if … else if

    除了双分支结构,程序还可以多条路径中选择一条去执行,也就是if …else if的基础上,增加多个条件表达式,判断这个表达式可以用else if完成,流程图如下:

    多分支if … else if条件判断语法如下:

    if (条件表达式1) {
    语句块1;
    } else if (条件表达式2) {
    语句块2;
    }

    else {
    语句块n;
    }

    如果条件表达式1成立,则执行语句块1, 否则继续判断条件表达式2,如果条件表达式2成立,则执行语句块2,依次类推,如果条件表达式都不成立,则执行else中的语句块n+1。

    注意事项:

    1. 可以有多个else if 语句块;
    2. 单独的else语句块只能放在最后,不可以提到前面,该块是可选的。

    示例:

    根据输入的成绩判断成绩等级:

    1. 大于等于90分,优秀;
    2. 大于等于80分,小于90分,中等;
    3. 大于等于70分,小于80分,良;
    4. 大于等于60分,小于70分,及格;
    5. 小于60分,不及格。
    public class Example09 {
    	public static void main(String[] args) {
    		int grade = 75; 		// 定义学生成绩
    		if (grade > 90) {
    			// 满足条件 grade > 90
    			System.out.println("该成绩的等级为优");
    		} else if (grade > 80) {
    			// 不满足条件 grade > 90 ,但满足条件 grade > 80 
    			System.out.println("该成绩的等级为良");
    		} else if (grade > 70) {
    			// 不满足条件 grade > 80 ,但满足条件 grade > 70 
    			System.out.println("该成绩的等级为中");      
    		} else if (grade > 70) {
    			// 不满足条件 grade > 80 ,但满足条件 grade > 70 
    			System.out.println("该成绩的等级为中");else {
    			// 不满足条件 grade > 60 
    			System.out.println("该成绩的等级为差");
    		}    
    	}    
     }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20

    3.3 分支结构 switch-case

    switch-case提供多分支程序结构语句。当多分支中的条件表达式是对同一个变量或表达式进行等值判断时,往往使用它代替实现。

    3.3.1 分支结构 switch-case

    switch语句好比是多路开关,流程图如下:


    其语法结构如下:

    switch(变量或表达式){
    case 常量1;
    语句1;
    break;
    case 常量2;
    语句2;
    break;

    case 常量N:
    语句N
    default;
    语句;
    break;
    }

    swith结构的执行过程是先获取变量或表达式的值,然后从上往下依次匹配各个case后的常量值,判断是否与之相等。如果匹配成功,则执行case后的语句,直到遇见break或switch执行结束为止;如果匹配不成功,则执行default后的语句,直到遇见break或switch执行结束为止。
    switch的执行特点有几个关键词:入口、出口、贯穿。
    所谓入口,是指进入switch的某个分支开始执行,它有两种情况:

    1. 如果switch(变量或表达式)的值与某个case后面的常量值相匹配,那么就从这个case进入。
    2. 如果switch(变量或表达式)的值与所有case后面的常量值都不匹配,那么就从default进入。

    所谓出口,是指一旦找到入口,switch结构可能从一个分支贯穿执行到下一个分支,直到遇到出口为止。无论是与case还是default匹配成功,在遇到break或switch结束大括号前,会一直贯穿向下执行,直到遇到出口为止。

    注意事项:

    1. switch()中的变量或表达式的类型在JDK5前只能是int类型,或者int类型的兼容类型byte、short、char,在JDK5后开始支持枚举类型,在JDK7后开始支持Strin类型。
    2. case后只能是常量值,不能是变量或表达式。
    3. case后的常量值不能重复。
    4. case语句块中如果没有break,则将贯穿下面的case或default中的语句,不再判断是否相等。

    示例:以下语句是否正确?如正确,输出结果是多少?

    public class TestDefault{
        public static void main(String[] args){
            int x = 100;
            int a = 2;
            switch(a){
                case 1:
                    x += 5;
                default:
                    x += 34;
                case 2:
                    x += 10;
                case 3:
                    x += 16 
            }
            System.out.println("x = " + x);
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17

    3.3.2 分支结构与条件判断的区别

    1. if语句和switch语句的比较:
      1. switch语句只支持常量值相等的分支判断,而if语句的支持更为灵活,任意的布尔表达式均可;
      2. switch语句通常比一系列嵌套if语句效率更高,逻辑更加清洗。
    2. if语句和switch语句的使用场景:
      1. switch语句建议用来判断固定值,且此时的固定值的取值范围不大;
      2. if语句建议用来判断区间或范围;
      3. switch语句能做的,if都能做,反之不行。

    案例:用键盘分别输入年、月、日,判断这一天是当年的第几天。

    import java.util.Scanner;
    
    public class DaysOfYearDemo{
    
        public static void main(String[] args){
        
            Scanner input = new Scanner(System.in);
            
            System.out.print("年:");
            int year = input.nextInt();
            
            System.out.print("月:");
            int month = input.nextInt();
            
            System.out.print("日:");
            int day = input.nextInt();
            
            // 声明一个变量days,用来存储总天数
            int days = 0;
            
            // 累加[1, month-1]个月满月天数和第month月的day天
            switch(month){
                case 12:
                    days += 30; //11月
                case 11:
                    days += 31; //10月   
                case 10:
                    days += 30; //9月
                case 9:
                    days += 31; //8月
                case 8:
                    days += 31; //7月
                case 7:
                    days += 30; //6月
                case 6:
                    days += 31; //5月
                case 5:
                    days += 30; //4月
                case 4:
                    days += 31; //3月
                case 3:
                    days += 28; //2月
                    if ((year % 4 == 0 && year % 100 !=0) || year % 400 == 0){
                        days++; //闰年多加一天
                    }
                case 2:
                    days += 31; //1月
                case 1:
                    days += day; //累加第month月的day天        
            }
            System.out.println(year + "年" + month + "月" + day + "日是这一年的第" + days + "天");   
        }
    }
    
    • 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
    • 50
    • 51
    • 52
    • 53

    3.4 循环结构

    循环结构是指在某些条件满足的情况下,反复执行某段代码的结构。循环结构由循环条件来判断继续执行某个功能还是退出循环。

    1. 循环结构主要有以下三种形式:
      1. while语句;
      2. do while语句;
      3. for语句。
    2. 循环结构的四要素:
      1. 初始化表达式。循环变量的初始化表达式。
      2. 循环条件。反复执行代码所需的条件,必须是布尔型。如果是true,则执行循环体。如果是false,则跳出循环体。如果没有条件,或者条件恒成立,则为死循环。
      3. 循环体。反复执行的代码。
      4. 迭代表达式。循环变量值的修改,只有不断地修改循环变量的值,才会使循环终止。

    3.4.1 while语句

    while语句是一种先判断的循环结构,只要条件成立,就会执行大括号内的语句,直到条件不成立,while循环结束。流程图如下:

    while语句循环条件的结果只能是布尔型的变量或值,这点和if语句的条件表达式相同。循环语句块如果只有一条语句,则可以省略大括号。

    示例:打印100次“Hello World!”

    public class TestWhile{
        public static void main(String[] args){
            int i = 1;
            while (i <= 100){
                System.out.println("Hello World!");
                i++;
            }
        }    
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    示例:趣味折纸,世界最高峰为珠穆朗玛峰,它的高度是8848.86米。假如我有一张足够大的纸,它的厚度是0.1毫米。请问我要对折多少次,才可以折成珠穆朗玛峰的高度?

    public class PaperFolding{
        public static void main(String[] args){
            // 定义一个计数器,初始值为0
            int count = 0;
            
            // 定义纸张厚度
            double paper = 0.1;
            
            // 定义珠穆朗玛峰的高度;
            int mountain = 8848860;
            
            // 一直折叠,直到厚度达到珠穆朗玛峰的高度
            while (paper <= mountain){
                // 循环的执行过程中每次纸张折叠,
                paper *= 2;
                
                // 循环中执行累加,对应折叠了多少次
                count++;
            }
            System.out.println("需要折叠:" + count + "次");
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22

    3.4.2 do … while语句

    do … while语句实现的是先执行后判断的循环,没有入口条件,直接执行循环操作,再判断循环条件。总体来看,do …while语句大致同while语句,只是少了入口条件,do … while语句的执行流程如下图:

    语法结构:

    初始化表达式;

    do {
    循环体;
    迭代表达式;
    } while (循环条件);

    示例:打印1~100的整数。

    public class TestDoWhile{
        public static void main(String[] args) {
            int i = 1;
            do {
                System.out.println(i);
                i++;                      
            } while (i <= 100);
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    每个循环结构都应该具备循环4要素:

    int i = 1; // 1.初始化表达式
    do {
        System.out.println(i); //3.循环体语句
        i++; // 4.迭代表达式
    } while (i <= 100); // 2.循环条件
    
    • 1
    • 2
    • 3
    • 4
    • 5

    while循环和do … while循环对比
    在这里插入图片描述

    示例:猜数字,随机生成一个[0, 100)以内的整数,然后猜这个数字是多少,如果用键盘输入的数大了,则提示猜大了,如果小了,则提示猜对了,并且结束。最后统计一共猜了多少次。
    提示:系统函数Math.random()可以返回一个[0,1)范围的double值。

    import java.util.Scanner;
    
    public class GuessNumber{
    
        public static void main(String[] args) {
            int num = (int) (Math.random() * 100);
            
            Scanner input = new Scanner(System.in);
            int guess;
            int count = 0;
            do{
                System.out.print("情输入[0, 100)的整数:");
                guess = input.nextInt();
                
                // 输入一次,就表示猜了一次
                count++;
                if (guess > num) {
                    System.out.println("猜大了!");
                } else if (guess < num) {
                     System.out.println("猜小了!");
                } else {
                     System.out.println("猜对了!");
                }
            } while (num != guess); 
        System.out.println("一共猜了:" + count + "次");
        }
    }
    
    • 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

    3.4.3 for语句

    循环结构最开始设计的是while结构,即强调循环条件成立就执行语句,直到循环条件不成立。而引入do … while结构是为了满足至少执行一次循环体语句块的需求。但在这个使用过程中,有一种情况很常见,那就是循环条件是一个区间值,从几循环到几,每次修改循环变量的迭代语句也很有规律,为了满足这种需求,设计了for循环结构。for循环结构的执行流程如下图所示:

    for循环语法结构:

    for ( 1.循环变量初始化; 2.循环条件; 4.循环变量迭代更新表达式) {
    3.循环体语句
    }

    说明:

    1. 两个分号必不可少,如果for括号中的三个表达式都省略,则相当于条件恒成立的"死循环"。
    for ( ; ;) {
    }
    
    • 1
    • 2
    1. 循环变量初始化可以由多条变量初始化语句组成,中间用逗号隔开。循环变量更新也可以由多条更新语句组成,中间用逗号隔开。
    for (int i = 1, j=10; i <=10; i++, j--) {
    }
    
    • 1
    • 2
    1. 循环条件部分为布尔型的表达式,当值为false时,退出循环。

    案例:使用for循环结构打印1~100的整数

    public class TestFor{
        public static void main (String[] args) {
            for (int i=1; i <= 100; i++) {
                System.out.println(i);
            }
        }  
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    3.4.4 嵌套循环

    一个循环语句中又完整地嵌套了另一个循环语句,称为嵌套循环或多重循环,也就是一个循环结构的循环体也为循环结构。其中for、while、do … while均可以作为外层循环和内层循环。外层循环如果循环一次,内层循环则需要循环一轮。

    案例:打印九九乘法表

    public class MultiplicationTable{
        public static void main(String[] args) {
            for (int i = 1; i<=9; i++) {
                for (int j = 1; j <= i; j++) {
                    System.out.print(j + "*" + i + "=" + (i * j) + "\t");
                }
                System.out.println();
            }
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    3.5 跳转语句

    跳转语句就是在中途改变程序原本的执行过程的语句。

    3.5.1 break语句

    break语句的意思是中断。break语句可以用于循环和switch结构,表示提前结束switch或当前循环。

    示例:猜数字,随机生成一个[0, 100)以内的整数,然后猜这个数字是多少,如果用键盘输入的数大了,则提示猜大了,如果小了,则提示猜对了,并且结束。最后统计一共猜了多少次。
    提示:系统函数Math.random()可以返回一个[0,1)范围的double值。

    import java.util.Scanner;
    
    public class GuessNumber1{
    
        public static void main(String[] args) {
            int num = (int) (Math.random() * 100);
            
            Scanner input = new Scanner(System.in);
            int guess;
            int count = 0;
            while (true) {
                System.out.print("情输入[0, 100)的整数:");
                guess = input.nextInt();
                
                // 输入一次,就表示猜了一次
                count++;
                if (guess > num) {
                    System.out.println("猜大了!");
                } else if (guess < num) {
                     System.out.println("猜小了!");
                } else {
                     System.out.println("猜对了!");
                     break;
                }
            } 
        System.out.println("一共猜了:" + count + "次");
        }
    }
    
    • 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

    3.5.2 continue语句

    continue语句的意思是继续。continue语句只能用在循环中,表示继续下一次循环,本次循环剩下的循环体语句将被跳出。

    public class TestContinue{
        public static void main(String[] args) {
            int i = 1;
            while (i <= 5) {
                if (i == 3) {
                    continue; //死循环
                }
                System.out.println("Hello" + i);
                i++;
            } 
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    案例:计算1~100之间能被3整除的数的和

    public class TestThree{
        public static void main(String[] args) {
            int total = 0;
            for (int i = 1; i <= 100; i++){
                if (i % 3 != 0) {
                    continue;
                } else {
                    total += i;
                }
            }
            System.out.println("1~100能被3整除的数之和为:" + total);
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    3.5.3 return语句

    return语句表示返回。return语句用在方法中的作用是结束所在方法。

  • 相关阅读:
    电容如何能做升压?(电荷泵的工作原理及特性)
    qt软件崩溃的分析方法-定位源文件和行号
    源码编译安装LNMP
    负载均衡取消后的记录
    查询企业信息的四种方法
    三维地质建模数据处理
    高等代数复习:同构定理
    独立站去中心化模式崛起,席卷跨境企业转型浪潮
    Cannot deserialize value of type `java.util.Date` from String
    jmeter 得使用线程租得详细介绍
  • 原文地址:https://blog.csdn.net/shield911/article/details/126879951