第三章 流程控制语句结构

第三章 流程控制语句结构

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

3.1 顺序结构

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

3.1.1 顺序结构的特点

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

3.1.2 输出语句

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

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

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);
	}
}

如果输入的是小数会报错,因为输入语句只接受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);
	}
}

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")

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

public class Example07 {
	public static void main(String[] args) {
		int x = 5;
		if (x < 10) {
			x++;
		}
		System.out.println("x=" + x);
	}
}

案例: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 + "天");
    }
}

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 + "是平年");
        }
    }
}

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("该成绩的等级为差");
		}    
	}    
 }

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);
    }
}

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 + "天");   
    }
}

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++;
        }
    }    
}

示例:趣味折纸,世界最高峰为珠穆朗玛峰,它的高度是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 + "次");
    }
}

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);
    }
}

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

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

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 + "次");
    }
}

3.4.3 for语句

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

for循环语法结构:

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

说明:

  1. 两个分号必不可少,如果for括号中的三个表达式都省略,则相当于条件恒成立的"死循环"。
for ( ; ;) {
}
  1. 循环变量初始化可以由多条变量初始化语句组成,中间用逗号隔开。循环变量更新也可以由多条更新语句组成,中间用逗号隔开。
for (int i = 1, j=10; i <=10; i++, j--) {
}
  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);
        }
    }  
}

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();
        }
    }
}

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 + "次");
    }
}

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~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);
    }
}

3.5.3 return语句

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

  • 2
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值