Java基本语法(下):程序流程控制顺序结构if-els

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

  • 流程控制语句是用来控制程序中各语句执行顺序的语句,可以把语句组合成能完成一定功能的小逻辑模块。

  • 其流程控制方式采用结构化程序设计中规定的三种基本流程结构,即:

    • 顺序结构
    • 分支结构
    • 循环结构

    1639356626.jpg

  • 顺序结构

    • 程序从上到下逐行地执行,中间没有任何判断和跳转。
  • 分支结构

    • 根据条件,选择性地执行某段代码。
    • 有if…else和switch-case两种分支语句。
  • 循环结构

    • 根据循环条件,重复性的执行某段代码。
    • 有while、do…while、for三种循环语句。
    • 注:JDK1.5提供了foreach循环,方便的遍历集合、数组元素。

顺序结构

image.png

Java中定义成员变量时采用合法的前向引用。如:

    public class Test{
        int num1 = 12;
        int num2 = num1 + 2;
    }
复制代码

错误形式:

public class Test{
    int num2 = num1 + 2;//num1未定义
    int num1 = 12;
}
复制代码

if-else结构

在Java程序中,如果要根据条件来决定是否执行某一段代码,就需要if语句。

三种基本语法

image.png
image.png

if-else使用说明

  • 条件表达式必须是布尔表达式(关系表达式或逻辑表达式)、布尔变量
  • 语句块只有一条执行语句时,一对{}可以省略,但建议保留
  • if-else语句结构,根据需要可以嵌套使用
  • 当if-else结构是“多选一”时,最后的else是可选的,根据需要可以省略
  • 当多个条件是“互斥”关系时,条件判断语句及执行语句间顺序无所谓,当多个条件是“包含”关系时,“小上大下 / 子上父下”

举例

public class AgeTest{
    public static void main(String args[]){
        int age = 75;
        if (age < 0) {
            System.out.println("不可能!");
        } else if (age > 250) {
            System.out.println("是个妖怪!");
        } else {
            System.out.println(“人家芳龄 " + age +" ,马马乎乎啦!");
        }
    }
}
复制代码

小结

  1. if ... else可以做条件判断,else是可选的;
  2. 如果if-else结构中的执行语句只有一行时,对应的一对{}可以省略的。但是,不推荐省略花括号{}
  3. 多个if ... else串联要特别注意判断顺序;
  4. 要注意if的边界条件;
  5. 要注意浮点数判断相等不能直接用==运算符;
  6. 引用类型判断内容相等要使用equals(),注意避免NullPointerException
  7. 针对于条件表达式:
    • 如果多个条件表达式之间是“互斥”关系(或没有交集的关系),哪个判断和执行语句声明在上面还是下面,无所谓。
    • 如果多个条件表达式之间有交集的关系,需要根据实际情况,考虑清楚应该将哪个结构声明在上面。
    • 如果多个条件表达式之间有包含的关系,通常情况下,需要将范围小的声明在范围大的上面。否则,范围小的就没机会执行了。
  8. if-else结构是可以相互嵌套的。

switch-case结构

除了if语句外,还有一种条件判断,是根据某个表达式的结果,分别去执行不同的分支。
例如,在游戏中,让用户选择选项:

  1. 单人模式
  2. 多人模式
  3. 退出游戏

这时,switch语句就派上用场了。
switch语句根据switch (表达式)计算的结果,跳转到匹配的case结果,然后继续执行后续语句,直到遇到break结束执行。

语法

image.png

举例

    public class SwitchTest1 {
        public static void main(String args[]) {
            int i = 1;
            switch (i) {
                case 0:
                    System.out.println("zero");
                break;
                case 1:
                    System.out.println("one");
                break;
                default:
                    System.out.println("default");
                break;
            }
        }
    }
复制代码
    public class SwitchTest2 {
        public static void main(String args[]) {
            String season = "summer";
            switch (season) {
                case "spring":
                    System.out.println("春暖花开");
                break;
                case "summer":
                    System.out.println("夏日炎炎");
                break;
                case "autumn":
                    System.out.println("秋高气爽");
                break;
                case "winter":
                    System.out.println("冬雪皑皑");
                break;
                default:
                    System.out.println("季节输入有误");
                break;
            }
        }
    }
复制代码

规则

  • switch(表达式)中表达式的值必须是下述几种类型之一:byte,short,char,int,枚举 (jdk 5.0),String (jdk 7.0);
  • case子句中的值必须是常量,不能是变量名或不确定的表达式值;
  • 同一个switch语句,所有case子句中的常量值互不相同;
  • break语句用来在执行完一个case分支后使程序跳出switch语句块;如果没有break,程序会顺序执行到switch结尾,如果遗漏了break,就容易造成严重的逻辑错误,而且不易在源代码中发现错误。
  • default子句是可选的。同时,位置也是灵活的。当没有匹配的case时,执行default

switch和if语句的对比

if和switch语句很像,具体什么场景下,应用哪个语句呢?

  • 如果判断的具体数值不多,而且符合byte、short 、char、int、String、枚举等几种类型。虽然两个语句都可以使用,建议使用swtich语句。因为效率稍高
  • 其他情况:对区间判断,对结果为boolean类型判断,使用if,if的使用范围更广。也就是说,使用switch-case的,都可以改写为if-else。反之不成立。

小结

  1. 根据switch表达式中的值,依次匹配各个case中的常量。一旦匹配成功,则进入相应case结构中,调用其执行语句。当调用完执行语句以后,则仍然继续向下执行其他case结构中的执行语句,直到遇到break关键字或此switch-case结构末尾结束为止。
  2. break,可以使用在switch-case结构中,表示一旦执行到此关键字,就跳出switch-case结构
  3. switch结构中的表达式,只能是如下的6种数据类型之一:byte 、short、char、int、枚举类型(JDK5.0新增)、String类型(JDK7.0新增)
  4. case 之后只能声明常量。不能是变量名或不确定的表达式值。
  5. break关键字是可选的
  6. default:相当于if-else结构中的else;default结构是可选的,而且位置是灵活的。
  7. 如果switch-case结构中的多个case的执行语句相同,则可以考虑进行合并。
  8. break在switch-case中是可选的

循环结构

循环语句就是让计算机根据条件做循环计算,在条件满足时继续循环,条件不满足时退出循环。

  • 循环结构
    • 在某些条件满足的情况下,反复执行特定代码的功能
  • 循环语句分类
    • for 循环
    • while 循环
    • do-while 循环

循环语句的四个组成部分

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

image.png

for循环

Java使用最广泛的是for循环。
for循环的功能非常强大,它使用计数器实现循环。for循环会先初始化计数器,然后,在每次循环前检测循环条件,在每次循环后更新计数器。计数器变量通常命名为i

语法格式

image.png

执行过程:

①-②-③-④-②-③-④-②-③-④-.....-②

说明:

  • ②循环条件部分为boolean类型表达式,当值为false时,退出循环
  • ①初始化部分可以声明多个变量,但必须是同一个类型,用逗号分隔
  • ④可以有多个变量更新,用逗号分隔

image.png

举例

    public class ForLoop {
        public static void main(String args[]) {
            int result = 0;
            for (int i = 1; i <= 100; i++) {
                result += i;
            }
            System.out.println("result=" + result);
        }
    }
复制代码

while循环

循环语句就是让计算机根据条件做循环计算,在条件满足时继续循环,条件不满足时退出循环。
while循环在每次循环开始前,首先判断条件是否成立。如果计算结果为true,就把循环体内的语句执行一遍,如果计算结果为false,那就直接跳到while循环的末尾,继续往下执行。

语法

image.png

执行过程:

①-②-③-④-②-③-④-②-③-④-...-②

说明:

  • 注意不要忘记声明④迭代部分。否则,循环将不能结束,变成死循环。
  • for循环和while循环可以相互转换

举例

    public class WhileLoop {
        public static void main(String args[]) {
            int result = 0;
            int i = 1;
            while (i <= 100) {
                result += i;
                i++;
            }
            System.out.println("result=" + result);
        }
    }
复制代码

do-while循环

语法格式

image.png

执行过程:

①-③-④-②-③-④-②-③-④-...②

说明

do while循环先执行循环,再判断条件;
do while循环会至少执行一次。

举例

    public class DoWhileLoop {
        public static void main(String args[]) {
            int result = 0, i = 1;
            do {
                result += i;
                i++;
            } while (i <= 100);
            System.out.println("result=" + result);
        }
    }
复制代码

嵌套循环(多重循环)

  • 将一个循环放在另一个循环体内,就形成了嵌套循环。其中,for ,while ,do…while均可以作为外层循环内层循环
  • 实质上,嵌套循环就是把内层循环当成外层循环的循环体。当只有内层循环的循环条件为false时,才会完全跳出内层循环,才可结束外层的当次循环,开始下一次的循环。
  • 设外层循环次数为m次,内层为n次,则内层循环体实际上需要执行m*n次。

说明

嵌套循环:将一个循环结构A声明在另一个循环结构B的循环体中,就构成了嵌套循环
内层循环:循环结构A
外层循环:循环结构B
① 内层循环结构遍历一遍,只相当于外层循环循环体执行了一次
② 假设外层循环需要执行m次,内层循环需要执行n次。此时内层循环的循环体一共执行了m * n次
③ 外层循环控制行数,内层循环控制列数

示例

    for(int j = 1;j <= 4;j++ ){
        for(int i = 1;i <= 6;i++){
             System.out.print('*');
        }
        System.out.println();
    }
复制代码
    for(int i = 1;i <= 5;i++){//控制行数
        for(int j = 1;j <= i;j++){//控制列数
            System.out.print("*");
        }
        System.out.println();
    }
复制代码

break和continue

无论是while循环还是for循环,有两个特别的语句可以使用,就是break语句和continue语句。

break语句

break语句总是跳出自己所在的那一层循环

image.png

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);
            }
            System.out.println("Game Over!");
        }
    }
复制代码

continue 语句

break会跳出当前循环,也就是整个循环都不会执行了。
continue则是提前结束本次循环,直接继续执行下次循环。

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

continue语句用法举例

    public class ContinueTest {
        public static void main(String args[]){
            for (int i = 0; i < 100; i++) {
                if (i%10==0)
                continue;
                System.out.println(i);
            }
        }
    }
复制代码

return的使用

特殊流程控制语句

  • return:并非专门用于结束循环的,它的功能是结束一个方法。当一个方法执行到一个return语句时,这个方法将被结束。
  • 与break和continue不同的是,return直接结束整个方法,不管这个return处于多少层循环之内

特殊流程控制语句说明

  • break只能用于switch语句循环语句中。
  • continue 只能用于循环语句中。
  • 二者功能类似,但continue是终止本次循环,break是终止本层循环
  • break、continue之后不能有其他的语句,因为程序永远不会执行其后的语句。
  • 标号语句必须紧接在循环的头部。标号语句不能用在非循环语句的前面。
  • 很多语言都有goto语句,goto语句可以随意将控制转移到程序中的任意一条语句上,然后执行它。但使程序容易出错。Java中的break和continue是不同于goto的。

衡量一个功能代码的优劣

  1. 正确性
  2. 可读性
  3. 健壮性
  4. 高效率与低存储:时间复杂度 、空间复杂度 (衡量算法的好坏)

补充:Scanner类的使用

java.util.Scanner 是 Java5 的新特征,我们可以通过 Scanner 类来获取用户的输入。

具体实现步骤

  1. 导包:import java.util.Scanner;
  2. Scanner的实例化:Scanner scan = new Scanner(System.in);
  3. 调用Scanner类的相关方法(next() / nextXxx()),来获取指定类型的变量

next() 与 nextLine() 区别

next():

  • 1、一定要读取到有效字符后才可以结束输入。
  • 2、对输入有效字符之前遇到的空白,next() 方法会自动将其去掉。
  • 3、只有输入有效字符后才将其后面输入的空白作为分隔符或者结束符。
  • next() 不能得到带有空格的字符串。

nextLine()

  • 1、以Enter为结束符,也就是说 nextLine()方法返回的是输入回车之前的所有字符。
  • 2、可以获得空白。

注意

需要根据相应的方法,来输入指定类型的值。如果输入的数据类型与要求的类型不匹配时,会报异常InputMisMatchException导致程序终止。

示例

import java.util.Scanner;

class ScannerTest{
	
	public static void main(String[] args){
		//2.Scanner的实例化
		Scanner scan = new Scanner(System.in);
		
		//3.调用Scanner类的相关方法
		System.out.println("请输入你的姓名:");
		String name = scan.next();
		System.out.println(name);

		System.out.println("请输入你的芳龄:");
		int age = scan.nextInt();
		System.out.println(age);

		System.out.println("请输入你的体重:");
		double weight = scan.nextDouble();
		System.out.println(weight);

		System.out.println("你是否相中我了呢?(true/false)");
		boolean isLove = scan.nextBoolean();
		System.out.println(isLove);

		//对于char型的获取,Scanner没有提供相关的方法。只能获取一个字符串
		System.out.println("请输入你的性别:(男/女)");
		String gender = scan.next();//"男"
		char genderChar = gender.charAt(0);//获取索引为0位置上的字符
		System.out.println(genderChar);	
	}
}
复制代码