Java流程控制语句


转载于:http://c.biancheng.net/java/80/
流程是人们生活中不可或缺的一部分,它表示人们每天都在按照一定的流程做事。比如出门搭车、上班、下班、搭车回家。这其中的步骤是有顺序的。程序设计也需要有流程控制语句来完成用户的要求,根据用户的输入决定程序要进入什么流程,即“做什么”以及“怎么做”等。

从结构化程序设计角度出发,程序有 3 种结构:顺序结构、选择结构和循环结构。若是在程序中没有给出特别的执行目标,系统则默认自上而下一行一行地执行该程序,这类程序的结构就称为顺序结构。

到目前为止,我们所编写的程序都属于顺序结构。但是事物的发展往往不会遵循早就设想好的轨迹进行,因此,所设计的程序还需要能够具有在不同的条件下处理不同问题以及当需要进行一些相同的重复操作时,如何能省时省力地解决问题的能力。

在本章中,我们将对 Java 程序中的上述3种流程结构进行学习。初学者应该对本章的每个小节进行仔细阅读、思考,这样才能达到事半功倍的效果。

Java语句:Java空语句、复合语句和表达式语句

按照语句的组成部分,可以将顺序结构中的语句分为表达式语句、空语句和复合语句 3 大类。下面首先介绍 Java 中语句的编写方式,然后对这 3 类语句进行详细介绍。

语句编写方式

在 Java 中,语句是最小的组成单位,每个语句必须使用分号作为结束符。除此之外,Java 对语句无任何其他限制,开发人员可以很随意地用符合自己风格的方式编写语句。

例如,可以将一个语句放在多行中,示例如下:

String str = "Apple "
+"Banner "+"Pear "
+" Orange";

由于 Java 使用分号作为语句的结束符,所以上面的 3 行代码会被 Java 认为是一条语句,因为这 3 行中只有一个分号。但是,我们不推荐使用这种方式来编写语句。

同样,因为使用分号作为分隔符,将多个语句放在一行来编写也是允许的。例如,下面的示例代码也是正确的。

int a=0,b,c;b=a+10;b++;c=a*b;System.out.println(c);

上面将 5 个语句放在一行中。

为了使程序语句排列得更加美观、容易阅读和排除错误,一般使用如下规则格式化源代码。

  • 在一行内只写一个语句,并采用空格、空行来保证语句容易阅读。
  • 在每个复合语句内使用 Tab 键向右缩进。
  • 大括号总是放在单独的一行,便于检查是否匹配。

空语句

所谓空语句(Empty Statement),它在程序中什么都不做,也不包含具有实际性的语句。在程序中,空语句主要用来作为空循环体。

空语句的语法格式如下:

; // 其实就是一个分号

执行一个空语句就是将控制转到该语句的结束点。这样,如果空语句是可到达的,则空语句的结束点也是可到达的。

表达式语句

在很多的高级语言中,有专门的赋值语句。而在 Java 中将赋值作为一个运算符,因此只有赋值表达式。在赋值表达式后面添加分号就成了独立的语句。

以下是一些表达式的示例语句:

3.1415926;
(a+b)/2;
x*y*z-y+(20-x);

这些表达式能够被 Java 编译器识别,但是由于没有对程序进行任何操作,因此无任何意义。

一般表达式语句应该能完成一个操作,如修改变量的值或者作为函数参数等。具体方法是,在表达式的左侧指定一个变量来存储表达式的值,或者将表达式传递给函数。

以下是修改后的表达式语句:

pi = 3.1415926;
output(pi); // 将pi的值传递到output()函数中作为参数
sum = (a+b)/2;
printf("%f",sum); // 将sum的值传递到printf()函数输出
temp = x*y*z-y+(20-x); // 将表达式的值保存到temp变量中

复合语句

复合语句又称为语句块,是很多个语句的组合,从而可以将多个语句看作单个语句。

复合语句的语法格式如下:

{
    statement-list // 语句列表
}

可以看到由一个扩在大括号内的可选 statement-list 组成。statement-list 是由一个或者多个语句组成的列表,如果不存在 statement-list,则称该语句块是空的。

它的执行规则如下:

  • 如果语句块是空的,控制转到语句块的结束点。
  • 如果语句块不是空的,控制转到语句列表。当控制到达语句列表的结束点时,控制转到语句的结束点。
例 1

创建一个语句块,该语句块包含 3 条语句。

{
    width = 10; // 为width变量赋值
    height = 90; // 为height变量赋值
    area = width * height; // 计算width变量和height变量的乘积
}

上述代码执行后,sum 变量的值为 900。上述的语句块中大括号内包含了 3 条语句。第一条语句为 width 变量赋值,第二条语句为 height 变量赋值,第三条语句则将 width 和 height 相乘,结果保存在 sum 变量中。

Java if else分支结构精讲

Java 支持两种选择语句:if 语句和 switch 语句。其中 if 语句使用布尔表达式或布尔值作为分支条件来进行分支控制,而 switch 语句则用于对多个整型值进行匹配,从而实现分支控制。这些语句允许你只有在程序运行时才能知道其状态的情况下,控制程序的执行过程。如果你没有 C/C++ 的编程背景,你将会为这两个语句的强大功能和灵活性而感到吃惊。

选择结构(也叫分支结构)解决了顺序结构不能判断的缺点,可以根据一个条件判断执行哪些语句块。选择结构适合于带有逻辑或关系比较等条件判断的计算。例如,判断是否到下班时间,判断两个数的大小等。

由于篇幅有限,本节主要介绍 if 语句的各种形式和用法。关于 switch 语句的用法我们会在《Java switch case》一节中讲解。

if 结构

if 语句是使用最多的条件分支结构,它属于选择语句,也可以称为条件语句。

if 选择结构是根据条件判断之后再做处理的一种语法结构。默认情况下,if 语句控制着下方紧跟的一条语句的执行。不过,通过语句块,if 语句可以控制多个语句。

if 语句的最简语法格式如下,表示“如果满足某种条件,就进行某种处理”。

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

其中“条件表达式”和“语句块”是比较重要的两个地方。

  1. 条件表达式:条件表达式可以是任意一种逻辑表达式,最后返回的结果必须是一个布尔值。取值可以是一个单纯的布尔变量或常量,也可以是使用关系或布尔运算符的表达式。如果条件为真,那么执行语句块;如果条件为假,则语句块将被绕过而不被执行。
  2. 语句块:该语句块可以是一条语句也可以是多条语句。如果仅有一条语句,可省略条件语句中的大括号 {}。当从编程规范角度不要省略大括号,省略大括号会使程序的可读性变差。

if 条件语句的运行流程如图 1 所示。

img
图1 if 语句执行流程图

例 1

编写一个 Java 程序,允许用户从键盘输入一个数字,再判断该数是否大于 100。使用 if 语句的实现代码如下:

public static void main(String[] args) {
    System.out.println("请输入一个数字:");
    Scanner input = new Scanner(System.in);
    int num = input.nextInt(); // 接收键盘输入数据
    // 判断用户输入的数据是否大于100
    if (num > 100) {
        System.out.println("输入的数字大于100");
    }
    // 判断用户输入的数据是否等于100
    if (num == 100) {
        System.out.println("输入的数字等于100");
    }
    // 判断用户输入的数据是否小于100
    if (num < 100) {
        System.out.println("输入的数字小于100");
    }
}

运行该程序,分别使用键盘输入 99、100 和 105,结果如下所示:

请输入一个数字:
99
输入的数字小于100
请输入一个数字:
100
输入的数字等于100
请输入一个数字:
105
输入的数字大于100
例 2

假设有 num1 和 num2 两个变量,它们的值分别是 50 和 34。下面编写程序,要求使用 if 语句判断 num1 和 num2 的大小关系,并输出比较结果。

实现代码如下:

public static void main(String[] args) {
    int num1 = 50;
    int num2 = 34;
    if (num1 > num2) {
        System.out.println("num1大于num2");
    }
    if (num1 == num2) {
        System.out.println("num2等于num2");
    }
    if (num1 < num2) {
        System.out.println("num1小于num2");
    }
}

该段选择语句判断了 num1 值和 num2 值的大于、等于和小于关系。此处 num1 为 50,num2 为 34,所以执行后会输出“num1 大于 num2”。

例 3

在上述两个案例代码中,由于每个 if 语句的语句块中只包含一条语句,所以省略了大括号。本实例在登录系统中要求用户名、密码和验证码都必须正确,否则将显示登录失败及错误提示。其中的语句块有多条语句,所以需要使用大括号。代码如下:

public static void main(String[] args) {
    String username = "admin"; // 用户名
    String userpass = "123456"; // 密码
    String code = "0000"; // 验证码
    if (username != "admin" && userpass != "123456" && code != "0000") {
        System.out.println("登录失败!");
        System.out.println("请检查输入的用户名、密码和验证码是否正确!");
    }
}

在这里为 if 语句设置了一个复杂的复合表达式来验证登录条件。执行后的输出结果如下:

登录失败!
请检查输入的用户名、密码和验证码是否正确!

if-else 结构

单 if 语句仅能在满足条件时使用,而无法执行任何其他操作(停止)。而结合 else 语句的 if 可以定义两个操作,此时的 if…else 语句表示“如果条件正确则执行一个操作,否则执行另一个操作”。

使用 if…else 语句的语法格式如下所示:

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

在上述语法格式中,如果 if 关键字后面的表达式成立,那么就执行语句块 1,否则的话则执行语句块 2,其运行流程如图 2 所示。

img

图2 if…else 运行流程

例 4

在例 3 中为实现比较 num1 和 num2 的大小,使用了 3 个 if 条件语句分别判断大于、等于和小于的情况。下面使用 if…else 双条件来实现,具体代码如下:

public static void main(String[] args) {
    int num1 = 50;
    int num2 = 34;
    // 如果num1等于num2
    if (num1 == num2) {
        System.out.println("num1等于num2");
    }
    // 如果num1大于num2
    if (num1 > num2) {
        System.out.println("num1大于num2");
    } else {
        // 否则就是num1小于num2
        System.out.println("num1小于num2");
    }
}

双条件语句减少了代码的编写量,同时增强了程序的可读性。简化后的结果还是一样,执行后会输出“num1 大于 num2”。

多条件 if-else-if 语句

if 语句的主要功能是给程序提供一个分支。然而,有时候程序中仅仅多一个分支是远远不够的,甚至有时候程序的分支会很复杂,这就需要使用多分支的 if…else if 语句。

通常表现为“如果满足某种条件,就进行某种处理,否则如果满足另一种条件才执行另一种处理……,这些条件都不满足则执行最后一种条件”。

if…else if 多分支语句的语法格式如下所示:

if(表达式1) {
    语句块1;
} else if(表达式2) {
    语句块2;
...
} else if(表达式n) {
    语句块n;
} else {
    语句块n+1;
}

可以看出,else-if 结构实际上是 if-else 结构的多层嵌套。明显的特点就是在多个分支中只执行一个语句组,而其他分支都不执行,所以这种结构可以用于有多种判断结果的分支中。

在使用 if…else if 语句时,依次判断表达式的值,当某个分支的条件表达式的值为 true 时,则执行该分支对应的语句块,然后跳到整个 if 语句之外继续执行程序。如果所有的表达式均为 false,则执行语句块 n+1,然后继续执行后续程序,其运行流程如图 3 所示。

img

图3 if…else if 语句的执行流程

例 5

同样以比较 num1 和 num2 的大小为例,使用 if…else if 多条件的实现代码如下:

public static void main(String[] args) {
    int num1 = 50;
    int num2 = 34;
    if (num1 == num2) { // 如果num1等于num2
        System.out.println("num1等于num2");
    } else if (num1 > num2) { // 如果num1大于num2
        System.out.println("num1大于num2");
    } else { // 否则就是小于
        System.out.println("num1小于num2");
    }
}

如上述代码所示,num1 和 num2 不满足 if 语句的“num1==num2”条件,接着测试 else if 的“num1>num2”条件,满足该条件并输出“num1 大于 num2”。

例 6

假设某学校对成绩的判断标准是:不低于 90,可以评为优秀;低于 90 但不低于 80,可以评为良好;低于 80 但不低于 60,可以评为中等;否则评为差。

public static void main(String[] args) {
    System.out.println("请输入考试成绩:");
    Scanner input = new Scanner(System.in);
    int score = input.nextInt(); // 接收键盘输入数据
    if (score >= 90) { // 考试成绩>=90
        System.out.println("优秀");
    } else if (score >= 80) { // 90>考试成绩>=80
        System.out.println("良好");
    } else if (score >= 60) { // 80>考试成绩>=60
        System.out.println("中等");
    } else { // 考试成绩<60
        System.out.println("差");
    }
}

当考试成绩为 90 分以上时,则执行第一个 if 语句,下面的 3 个条件判断语句不会执行;当考试成绩为 80 分以上 90 分以下时,则执行第一个 else if 语句;当考试成绩在 60~80 分,并且包含 60 分的成绩,则执行第二个 else if 语句;如果上述 3 个条件都不满足,则执行 else 语句。

程序运行后的输出效果如下所示:

请输入考试成绩:
100
优秀
请输入考试成绩:
88
良好
请输入考试成绩:
50
差

嵌套 if 的使用

if 语句的用法非常灵活,不仅可以单独使用,还可以在 if 语句里嵌套另一个 if 语句。同样,if…else 语句和 if…else if 语句中也可以嵌套另一个 if 结构的语句,以完成更深层次的判断。

嵌套 if 的语法格式如下:

if(表达式1) {
    if(表达式2) {
        语句块1;
    } else {
        语句块2;
    }
} else {
    if(表达式3) {
        语句块3;
    } else if(表达式4) {
        语句块4;
    } else {
        if(表达式n) {
            语句块n;
        } else {
            语句块n+1;
        }
    }
}

在上述格式中,应该注意每一条 else 与离它最近且没有其他 else 对应的 if 相搭配,其执行流程如图 4 所示。

img

图4 嵌套 if 语句执行流程

例 7

活动计划安排,如果今天是工作日,去上班;如果今天是周末,则出去游玩;同时,如果周末天气晴朗,去室外游乐场游玩,否则去室内游乐场游玩。实现代码如下:

public static void main(String[] args) {
    String today = "周末";
    String weather = "晴朗";
    if (today.equals("周末")) {
        if (weather.equals("晴朗")) {
            System.out.println("去室外游乐场游玩");
        } else {
            System.out.println("去室内游乐场游玩");
        }
    } else {
        System.out.println("去上班");
    }
}

如上述代码所示,today 满足 if 语句的“today.equals(“周末”)”条件,接着测试 weather 是否满足“weather.equals(“晴朗”)”条件,满足该条件输出“去室外游乐场游玩”。

Java switch case语句详解

if…else 语句可以用来描述一个“二岔路口”,我们只能选择其中一条路来继续走,然而生活中经常会碰到“多岔路口”的情况。switch 语句提供了 if 语句的一个变通形式,可以从多个语句块中选择其中的一个执行。

switch 语句格式

switch 语句是 Java 的多路分支语句。它提供了一种基于一个表达式的值来使程序执行不同部分的简单方法。因此,它提供了一个比一系列 if-else-if 语句更好的选择。

switch 语句的基本语法形式如下所示:

switch(表达式) {
    case1:
        语句块1;
        break;
    case2:
        语句块2;
        break;case 值n:
        语句块n;
        break;
    default:
        语句块n+1;
    break;
}

其中,switch、case、default、break 都是 Java 的关键字。

1)switch

表示“开关”,这个开关就是 switch 关键字后面小括号里的值,小括号里要放一个整型变量或字符型变量。表达式必须为 byte,short,int,char类型。

Java7 增强了 switch 语句的功能,允许 switch 语句的控制表达式是 java.lang.String 类型的变量或表达式。只能是 java.lang.String 类型,不能是 StringBuffer 或 StringBuilder 这两种字符串的类型。

2)case

表示“情况,情形”,case 标签可以是:

  • 类型为 char、byte、 short 或 int 的常量表达式。
  • 枚举常量。
  • 从 Java SE 7 开始, case 标签还可以是字符串字面量。

例如:

String input = ...;
switch (input.toLowerCase()) {  // toLowerCase用于将大写字符转换为小写
    case "yes":
        ...
        break;
}

当在 switch 语句中使用枚举常量时,不必在每个标签中指明枚举名,可以由 switch 的表达式值确定。例如:

Size sz = ...;
switch (sz) {
    case SMALL: // no need to use Size.SMALL
        ...
        break;
    ...
}

注意:重复的 case 值是不允许的。

3)default

表示“默认”,即其他情况都不满足。default 后要紧跟冒号,default 块和 case 块的先后顺序可以变动,不会影响程序执行结果。通常,default 块放在末尾,也可以省略不写。

4)break

表示“停止”,即跳出当前结构。

如果在 case 分支语句的末尾没有 break 语句,有可能触发多个 case 分支。那么就会接着执行下一个 case 分支语句。这种情况相当危险,常常会引发错误。为此,我们在程序中从不使用 switch 语句。

如果你喜欢 switch 语句,编译代码时可以考虑加上 -Xlint:fallthrough 选项,如下所示:

javac -Xlint:fallthrough Test.java

这样一来,如果某个分支最后缺少一个 break 语句,编译器就会给出一个警告消息。

switch 语句的执行过程如下:表达式的值与每个 case 语句中的常量作比较。如果发现了一个与之相匹配的,则执行该 case 语句后的代码。如果没有一个 case 常量与表达式的值相匹配,则执行 default 语句。当然,default 语句是可选的。如果没有相匹配的 case 语句,也没有 default 语句,则什么也不执行。

switch语句执行流程图

图 1 switch语句执行流程图

例 1

在节目的抽奖环节里,节目组会根据每位嘉宾的座位号来进行抽奖游戏,根据不同的号码来决定奖项的大小。使用 switch 语句编写 Java 程序来完成奖项分配,其实现代码如下。

public static void main(String[] args) {
    System.out.println("请输入座位号码:");
    Scanner sc = new Scanner(System.in);
    int num = sc.nextInt();
    switch (num) {
    case 8:
        System.out.println("恭喜你,获得了三等奖!");
        break;
    case 88:
        System.out.println("恭喜你,获得了二等奖!");
        break;
    case 888:
        System.out.println("恭喜你,获得了一等奖!");
        break;
    default:
        System.out.println("谢谢参与!");
        break;
    }
}

当用户输入的号码为 888 时,获取的 num 值为 888,则与第三个 case 后的值匹配,执行它后面的语句,输出“恭喜你,获得了一等奖!”,然后执行 break 语句,跳出整个 switch 结构。如果输入的号码与 case 中的值都不匹配,则执行 default 后的语句。

程序执行结果如下所示:

请输入座位号码:
888
恭喜你,获得了一等奖!
请输入座位号码:
88
恭喜你,获得了二等奖!
请输入座位号码:
66
谢谢参与!
例 2

编写一个 Java 程序,根据当前的星期数字输出对应的汉字。在这里使用包含 break 的 switch 语句来判断当前的星期,实现代码如下:

public static void main(String[] args) {
    String weekDate = "";
    Calendar calendar = Calendar.getInstance();  // 获取当前时间
    int week = calendar.get(Calendar.DAY_OF_WEEK) - 1;  // 获取星期的第几日
    switch (week) {
        case 0:
            weekDate = "星期日";
            break;
        case 1:
            weekDate = "星期一";
            break;
        case 2:
            weekDate = "星期二";
            break;
        case 3:
            weekDate = "星期三";
            break;
        case 4:
            weekDate = "星期四";
            break;
        case 5:
            weekDate = "星期五";
            break;
        case 6:
            weekDate = "星期六";
            break;
    }
    System.out.println("今天是 " + weekDate);
}

本程序首先获取当前的星期值,然后使用 switch 语句判断 week 的值:0 表示星期日,1 表示星期一,2 表示星期二……以此类推,6 表示星期六。只要 week 值与 case 值相符合,则程序将执行该 case 中的语句,并跳出 switch 语句,输出结果。

运行程序,输出的结果如下:

今天是星期五

嵌套 switch 语句

可以将一个 switch 语句作为一个外部 switch 语句的语句序列的一部分,这称为嵌套 switch 语句。因为一个 switch 语句定义了自己的块,外部 switch 语句和内部 switch 语句的 case 常量不会产生冲突。例如,下面的程序段是完全正确的:

public static void main(String[] args) {
    switch (count) {
        case 1:
            switch (target) {
            case 0:
                System.out.println("target is zero");
                break;
            case 1:
                System.out.println("target is one");
                break;
            }
            break;
        case 2: // ...
    }
}

本例中,内部 switch 语句中的case 1:语句与外部 switch 语句中的case 1:语句不冲突。变量 count 仅与外层的 case 语句相比较。如果变量 count 为 1,则变量 target 与内层的 case 语句相比较。

学到这里我们可以发现以下几点:

  • switch 语句不同于 if 语句的是 switch 语句仅能测试相等的情况,而 if 语句可计算任何类型的布尔表达式。也就是 switch 语句只能寻找 case 常量间某个值与表达式的值相匹配。
  • 在同一个 switch 语句中没有两个相同的 case 常量。当然,外部 switch 语句中的 case 常量可以和内部 switch 语句中的 case 常量相同。
  • switch 语句通常比一系列嵌套 if 语句更有效。

最后一点尤其有趣,因为它使我们知道 Java 编译器如何工作。当编译一个 switch 语句时,Java 编译器将检查每个 case 常量并且创造一个“跳转表”,这个表将用来在表达式值的基础上选择执行路径。因此,如果你需要在一组值中做出选择,switch 语句将比与之等效的 if-else 语句快得多。

编译器可以这样做是因为它知道 case 常量都是同类型的,所要做的只是将它与 switch 表达式相比较看是否相等。对于一系列的 if 表达式,编译器就无此功能。

if 语句和 switch 语句的区别

if 和 switch 语句都表示条件语句,可以从使用效率和实用性两方面加以区分。

1. 从使用效率上区分

从使用效率上区分,在对同一个变量的不同值作条件判断时,既可以使用 switch 语句,也可以使用 if 语句。使用 switch 语句的效率更高一些,尤其是判断的分支越多,越明显。

2. 从实用性上区分

从语句的实用性角度区分,switch 语句不如 if 条件语句,if 语句是应用最广泛和最实用的语句。

3. 何时使用 if 语句和 switch 语句

在程序开发的过程中,何时使用 if 语句和 switch 语句,需要根据实际情况而定,应尽量做到物尽其用。不能因为 switch 语句的效率高就一直使用,也不能因为 if 语句常用就不用 switch 语句。需要根据实际情况,具体问题具体分析,使用最适合的条件语句。

一般情况下,对于判断条件较少的,可以使用 if 条件语句,但是在实现一些多条件的判断中,最好使用 switch 语句。

Java while和do while循环详解

循环是程序中的重要流程结构之一。循环语句能够使程序代码重复执行,适用于需要重复一段代码直到满足特定条件为止的情况。

所有流行的编程语言中都有循环语句。Java 中采用的循环语句与C语言中的循环语句相似,主要有 while、do-while 和 for。另外 Java 5 之后推出了 for-each 循环语句,for-each 循环是 for 循环的变形,它是专门为集合遍历而设计的。for-each 并不是一个关键字。

循环语句可以在满足循环条件的情况下,反复执行某一段代码,这段被重复执行的代码被称为循环体。当反复执行这个循环体时,需要在合适的时候把循环条件改为假,从而结束循环,否则循环将一直执行下去,形成死循环。

循环语句可能包含如下 4 个部分。

  • 初始化语句(init statement): 一条或多条语句,这些语句用于完成一些初始化工作,初始化语句在循环开始之前执行。
  • 循环条件(test_expression):这是一个 boolean 表达式,这个表达式能决定是否执行循环体。
  • 循环体(body_statement):这个部分是循环的主体,如果循环条件允许,这个代码块将被重复执行。如果这个代码块只有一行语句,则这个代码块的花括号是可以省略的。
  • 迭代语句(iteration_statement):这个部分在一次循环体执行结束后,对循环条件求值之前执行,通常用于控制循环条件中的变量,使得循环在合适的时候结束。

上面 4 个部分只是一般性的分类,并不是每个循环中都非常清晰地分出了这 4 个部分。

由于篇幅有限,本文主要介绍 while 和 do-while。关于 for 循环,大家可以参考《Java for语句详解》一节。

while 语句

while 语句是 Java 最基本的循环语句,是一种先判断的循环结构,可以在一定条件下重复执行一段代码。该语句需要判断一个测试条件,如果该条件为真,则执行循环语句(循环语句可以是一条或多条),否则跳出循环。

while 循环语句的语法结构如下:

while(条件表达式) {
    语句块;
}

其中语句块中的代码可以是一条或者多条语句,而条件表达式是一个有效的 boolean 表达式,它决定了是否执行循环体。当条件表达式的值为 true 时,就执行大括号中的语句块。

执行完毕,再次检查表达式是否为 true,如果还为 true,则再次执行大括号中的代码,否则就跳出循环,执行 while 循环之后的代码。图 1 表示了 while 循环语句的执行流程。

img

图 1 while 循环语句执行流程图

例 1

使用 while 语句计算 10 的阶乘,其具体代码如下所示。

public static void main(String[] args) {
    int i = 1;
    int n = 1;
    while(i <= 10) {
        n=n*i;
        i++;
    }
    System.out.println("10的阶乘结果为:"+n);
}

在上述代码中,定义了两个变量 i 和 n,循环每执行一次 i 值就加 1,判断 i 的值是否小于等于 10,并利用 n=n*i 语句来实现阶乘。当 i 的值大于 10 之后,循环便不再执行并退出循环。

运行程序,执行的结果如下所示:

10 的阶乘结果为:3628800

do-while 语句

如你刚才所见,如果 while 循环一开始条件表达式就是假的,那么循环体就根本不被执行。然而,有时需要在开始时条件表达式即使是假的情况下,while 循环至少也要执行一次。换句话说,有时你需要在一次循环结束后再测试中止表达式,而不是在循环开始时。

幸运的是,Java就提供了这样的循环:do-while循环。do-while 循环语句也是 Java 中运用广泛的循环语句,它由循环条件和循环体组成,但它与 while 语句略有不同。do-while 循环语句的特点是先执行循环体,然后判断循环条件是否成立。

do-while 语句的语法格式如下:

do {
    语句块;
}while(条件表达式);

以上语句的执行过程是,首先执行一次循环操作,然后再判断 while 后面的条件表达式是否为 true,如果循环条件满足,循环继续执行,否则退出循环。while 语句后必须以分号表示循环结束,其运行流程如图 2 所示。

img

图 2 do-while 循环语句的执行流程

例 2

编写一个程序,计算 10 的阶乘。使用 do-while 循环的实现代码如下所示。

public static void main(String[] args) {
    int number = 1,result = 1;
    do {
        result*=number;
        number++;
    }while(number <= 10);
    System.out.print("10阶乘结果是:"+result);
}

程序运行后输出结果如下:

10 阶乘结果是:3628800
例 3

在一个图书系统的推荐图书列表中保存了 50 条信息,现在需要让它每行显示 10 条,分 5 行进行显示。下面使用 do-while 循环语句来实现这个效果,其具体代码如下所示。

public static void main(String[] args) {
    int bookIndex = 1;
    do {
        System.out.print(bookIndex+"\t");
        if(bookIndex%10 == 0) {
            System.out.println();
        }
        bookIndex++;
    }while(bookIndex<51);
}

在上述代码中, 声明一个变量 bookIndex 用来保存图书的索引,该变量赋值为 1 表示从第一本开始。在 do-while 循环体内,首先输出了 bookIndex 的值,然后判断 bookIndex 是否能被 10 整除,如果可以则说明当前行已经输出 10 条,用 System.out.println() 语句输出了一个换行符。之后使 bookIndex 加 1,相当于更新当前的索引。最后在 while 表达式中判断是否超出循环的范围,即 50 条以内。

运行程序,执行的结果如下所示。

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

while和do-while的比较

while 循环和 do-while 循环的相同处是:都是循环结构,使用 while(循环条件) 表示循环条件,使用大括号将循环操作括起来。

while 循环和 do-while 循环的不同处如下:

  • 语法不同:与 while 循环相比,do-while 循环将 while 关键字和循环条件放在后面,而且前面多了 do 关键字,后面多了一个分号。
  • 执行次序不同:while 循环先判断,再执行。do-while 循环先执行,再判断。
  • 一开始循环条件就不满足的情况下,while 循环一次都不会执行,do-while 循环则不管什么情况下都至少执行一次。

Java for循环详解

for 语句是应用最广泛、功能最强的一种循环语句。大部分情况下,for 循环可以代替 while 循环、do while 循环。

for 语句是一种在程序执行前就要先判断条件表达式是否为真的循环语句。假如条件表达式的结果为假,那么它的循环语句根本不会执行。for 语句通常使用在知道循环次数的循环中。

for 语句语法格式如下所示。

for(条件表达式1;条件表达式2;条件表达式3) {
    语句块;
}

for 循环中 3 个条件表达式的含义如表 1 所示。

表达式形式功能举例
条件表达式 1赋值语句循环结构的初始部分,为循环变量赋初值int i=1
条件表达式 2条件语句循环结构的循环条件i>40
条件表达式 3迭代语句,通常使用 ++ 或 – 运算符循环结构的迭代部分,通常用来修改循环 变量的值i++

for 关键字后面括号中的 3 个条件表达式必须用“;”隔开。for 循环中的这 3 部分以及大括号中使循环体必需的 4 个组成部分完美地结合在一起,简单明了。

for 循环语句执行的过程为:首先执行条件表达式 1 进行初始化,然后判断条件表达式 2 的值是否为 true,如果为 true,则执行循环体语句块;否则直接退出循环。最后执行表达式 3,改变循环变量的值,至此完成一次循环。接下来进行下一次循环,直到条件表达式 2 的值为 false,才结束循环,其运行流程如图 1 所示。

img

图 1 for循环执行流程图

值得指出的是,for 循环的循环迭代语句并没有与循环体放在一起,因此即使在执行循环体时遇到 continue 语句结束本次循环,循环迭代语句也一样会得到执行。

for 循环和 while、do while 循环不一样:由于 while、do while 循环的循环迭代语句紧跟着循环体,因此如果循环体不能完全执行,如使用 continue 语句来结束本次循环,则循环迭代语句不会被执行。但 for 循环的循环迭代语句并没有与循环体放在一起,因此不管是否使用 continue 语句来结束本次循环,循环迭代语句一样会获得执行。

与前面循环类似的是,如果循环体只有一行语句,那么循环体的大括号可以省略。

例如,同样是计算 5 的阶乘,使用 for 循环的实现代码如下:

public static void main(String[] args) {
    int result = 1;
    for (int number = 1; number <= 5; number++) {
        result *= number;
    }
    System.out.print("5 的阶乘结果是:" + result);   // 输出"5的阶乘结果是:120"
}

上述语句的含义可以理解为,将 number 变量的值从 1 开始,每次递增 1,直到大于 5 时终止循环。在循环过程中,将 number 的值与当前 result 的值进行相乘。

for 语句中初始化、循环条件以及迭代部分都可以为空语句(但分号不能省略),三者均为空的时候,相当于一个无限循环。下面对这些情况依次进行介绍。

1.条件表达式 1 为空

for 语句中条件表达式 1 的作用可以在程序的其他位置给出,所以当条件表达式 1 为空时,for 语句后面括号内其他条件表达式执行的顺序不变。

例如,使用 for 语句的这种形式计算 1~100 所有奇数的和。

public static void main(String[] args) {
    int result = 0;
    int number = 1; // 相当于for语句的第1个表达式
    for (; number < 101; number++) {
        if (number % 2 != 0) // 如果不能整除2,说明是奇数,则进行累加
            result += number;
    }
    System.out.print("100 以内所有奇数和为:" + result);
}

执行后的输出结果如下:

100 以内所有奇数和为:2500
2.条件表达式 2 为空

当 for 语句中条件表达式 2 为空时,将没有循环的终止条件。此时 for 语句会认为条件表达式 2 的值总是为真,循环无限制执行下去。因此,为了使循环达到某种条件时退出,需要在语句块中进行逻辑判断,并使用 break 语句来跳出循环,否则将产生死循环。

同样是计算 1~100 所有奇数的和,使用这种方式的代码如下。

public static void main(String[] args) {
    int result = 0;
    for (int number = 1;; number++) {
        if (number > 100)
            break; // 相当于for语句的表达式2,满足时就退出for循环
        if (number % 2 != 0) // 如果不能整除2,说明是奇数,则进行累加
            result += number;
    }
    System.out.print("100 以内所有奇数和为:" + result);
}
3.条件表达式 3 为空

当 for 语言中条件表达式 3 为空时,也就没有设置控制变量的表达式,即每次循环之后无法改变变量的值,此时也无法保证循环正常结束。

同样是计算1~100 所有奇数的和,使用这种方式的代码如下:

public static void main(String[] args) {
    int result = 0;
    for (int number = 1; number < 101;) {
        if (number % 2 != 0) // 如果不能整除2,说明是奇数,则进行累加
            result += number;
        number++; // 相当于for语句的条件表达式3,每次递增1
    }
    System.out.print("100 以内所有奇数和为:" + result);
}

如果没有循环体语句,number 变量的值为 1,永远小于 101,因此将无法结束循环,形成无限循环。在上面代码中将 number 的递增语句放在 for 循环体内,效果与完整 for 语句功能相同。

4.3 个条件表达式都为空

在 for 循环语句中,无论缺少哪部分条件表达式,都可以在程序的其他位置补充,从而保持 for 循环语句的完整性,使循环正常进行。

当 for 语句中循环体全为空时,即没有循环初值,不判断循环条件,循环变量不增值,此时无条件执行循环体,形成无限循环或者死循环。对于这种情况,读者在使用时应该尽量避免。

例如,计算 1~100 所有奇数的和,使用这种方式的代码如下:

public static void main(String[] args) {
    int result = 0;
    int number = 1; // 相当于for语句的条件表达式1
    for (;;) {
        if (number > 100)
            break; // 相当于for语句的条件表达式2
        if (number % 2 != 0) // 如果不能整除2,说明是奇数,则进行累加
            result += number;
        number++; // 相当于for语句的条件表达式3
    }
    System.out.print("100 以内所有奇数和为: " + result);
}
例 1

编写一个 Java 程序,统计某超市上半年的总销售量,要求由用户输入每月的销量。使用 for 循环的实现代码如下。

public static void main(String[] args) {
    int sum = 0;
    int num = 0;
    Scanner sc = new Scanner(System.in);
    for (int i = 1; i <= 6; i++) {
        System.out.println("请输入第" + i + " 个月的销售数量:");
        num = sc.nextInt();
        sum += num;
    }
    System.out.println("上半年的销售总量为:" + sum);
}

在该程序中, 声明循环变量 i,控制循环的次数,它被初始化为 1。每执行一次循环,都要对 i 进行判断,看其值是否小于等于 6,条件成立则继续累加成绩,否则退出循环。

每执行完一次循环体,都会对 i 累加 1。如此循环重复,直到 i 的值大于 6 时停止循环。此时退出 for 循环体,执行最下方的语句输出累加的销售总量。

运行程序,执行结果如下所示。

请输入第1 个月的销售数量:
6840
请输入第2 个月的销售数量:
5449
请输入第3 个月的销售数量:
6546
请输入第4 个月的销售数量:
2400
请输入第5 个月的销售数量:
908
请输入第6 个月的销售数量:
8048
上半年的销售总量为:30191

一般选择循环变量时,习惯选择 i、j、k 来作为循环变量。

for、do-while 和 while 的区别

在《Java while和do while循环》中我们学习了 do-while 和 while 循环,这一节我们又学习了 for 循环。关于 do-while 和 while 具体的相同点和不同点在刚刚提到的教程中已经介绍过了,在这里不过多讲解了。下面主要介绍它们的区别,如下表 2 所示。

名称概念适用场景特点
for根据循环次数限制做多少次重复操作适合循环次数是已知的操作初始化的条件可以使用局部变量和外部变量使用局部变量时,控制执行在 for 结束后会自动释放,提高内存使用效率。且变量在 for 循环结束后,不能被访问。先判断,再执行
while当满足什么条件的时候,才做某种操作适合循环次数是未知的操作初始化的条件只能使用外部变量,且变量在 while 循环结束后可以访问先判断,再执行
do-while先执行一次,在判断是否满足条件适合至少执行一次的循环操作在先需要执行一次的情况下,代码更加简洁。先执行一次,再判断
例 2

分别用 for、do-while 和 while 求出 1-10 的和。

1)使用for循环

代码如下:

public static void main(String[] args) {
    int sum = 0;
    for (int i = 1; i < 11; i++) {
        sum = sum + i;
    }
    System.out.println(sum);
}

运行结果为 55。

2)使用 do-while 循环

代码如下:

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

运行结果为 55。

3)使用 while 循环

代码如下:

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

运行结果为 55。

从上边代码可以看出 for 语句明显更加简练,因为知道循环次数。

Java foreach语句的用法

foreach 循环语句是 Java 1.5 的新特征之一,在遍历数组、集合方面,foreach 为开发者提供了极大的方便。foreach 循环语句是 for 语句的特殊简化版本,主要用于执行遍历功能的循环。

foreach 循环语句的语法格式如下:

for(类型 变量名:集合) {
    语句块;
}

其中,“类型”为集合元素的类型,“变量名”表示集合中的每一个元素,“集合”是被遍历的集合对象或数组。每执行一次循环语句,循环变量就读取集合中的一个元素,其执行流程如图 1 所示。

img
图 1 foreach 循环语句的执行流程图

例 1

假设有一个数组,采用 for 语句遍历数组的方式如下:

// 声明并初始化数组
int[] numbers = { 43, 32, 53, 54, 75, 7, 10 };
System.out.println("----for----");
// for语句
for (int i = 0; i < numbers.length; i++) {
    System.out.println("Count is:" + numbers[i]);
}

上述第 2 行语句声明并初始化了 7 个元素数组集合,目前大家只需要知道当初始化数组时,要把相同类型的元素放到 {…} 中并且用逗号分隔(,)即可。

关于数组集合会在教程后面详细介绍,这里我们只需要大概了解就可以。numbers.length 是获得数组的长度,length 是数组的属性,numbers[i] 是通过数组下标访问数组元素。

那么采用 for-each 循环语句遍历数组的方式如下:

// 声明并初始化int数组
int[] numbers = { 43, 32, 53, 54, 75, 7, 10 };
System.out.println("----for each----");
// for-each语句
for (int item : numbers) {
    System.out.println("Count is:" + item);
}

从示例中可以发现,item 不是循环变量,它保存了集合中的元素,for-each 语句将集合中的元素一一取出来,并保存到 item 中,这个过程中不需要使用循环变量,通过数组下标访问数组中的元素。可见 for-each 语句在遍历集合的时候要简单方便得多。

例 2
String[] urls = { "http://c.biancheng.net/java", "http://c.biancheng.net/c", "http://c.biancheng.net/golang/" };
// 使用foreach循环来遍历数组元素
// 其中book将会自动迭代每个数组元素
for (String url : urls) {
    System.out.println(url);
}

从上面程序可以看出,使用 foreach 循环遍历数组元素时无须获得数组长度,也无须根据索引来访问数组元素。

foreach 循环和普通循环不同的是,它无须循环条件,无须循环迭代语句,这些部分都由系统来完成,foreach 循环自动迭代数组的每个元素,当每个元素都被迭代一次后,foreach 循环自动结束。

当使用 foreach 循环来迭代输出数组元素或集合元素时,通常不要对循环变量进行赋值,虽然这种赋值在语法上是允许的,但没有太大的实际意义,而且极容易引起错误。例如下面程序。

String[] urls = { "http://c.biancheng.net/java", "http://c.biancheng.net/c", "http://c.biancheng.net/golang/" };
// 使用foreach循环来遍历数组元素,其中 book 将会自动迭代每个数组元素
for (String url : urls) {
    url = "https://c.biancheng.net";
    System.out.println(url);
}
System.out.println(urls[0]);

运行上边程序,将看到如下结果:

https://c.biancheng.net
https://c.biancheng.net
https://c.biancheng.net
https://c.biancheng.net/java

从上面运行结果来看,由于在 foreach 循环中对数组元素进行赋值,结果导致不能正确遍历数组元素,不能正确地取出每个数组元素的值。而且当再次访问第一个数组元素时,发现数组元素的值依然没有改变。

不难看出,当使用 foreach 来迭代访问数组元素时,foreach 中的循环变量相当于一个临时变量,系统会把数组元素依次赋给这个临时变量,而这个临时变量并不是数组元素,它只是保存了数组元素的值。因此,如果希望改变数组元素的值,则不能使用这种 foreach 循环。

使用 foreach 循环迭代数组元素时,并不能改变数组元素的值,因此不要对 foreach 的循环变量进行赋值。

例 3

在一个字符串数组中存储了几种编程语言,现在将这些编程语言遍历输出。

foreach 语句的实现代码如下:

public static void main(String[] args) {
    String[] languages={"Java","ASP.NET","Python","C#","PHP"};
    System.out.println("现在流行的编程语言有:");
    // 使用 foreach 循环语句遍历数组
    for(String lang:languages) {
        System.out.println(lang);
    }
}

在循环体执行的过程中,每循环一次,会将 languages 数组中的一个元素赋值给 lang 变量,直到遍历 languages 数组中所有元素,循环终止。

该程序运行后的结果如下所示。

现在流行的编程语言有:
Java
ASP.NET
Python
C#
PHP

Java return语句

return 关键字并不是专门用于结束循环的,return 语句用于终止函数的执行或退出类的方法,并把控制权返回该方法的调用者。如果这个方法带有返回类型,return 语句就必须返回这个类型的值;如果这个方法没有返回值,可以使用没有表达式的 return 语句。

return 语句的一般语法格式如下:

return 与方法相同类型的变量;

如果一个方法使用了 return 语句并且后面跟有该方法返回类型的值,那么调用此方法后,所得到的结果为该方法返回的值。

例 1

当用户输入两个 double 类型的数值后需要计算这两个数值之和,而这两个操作数是可以变动的,但是求和的功能是不变的,这时就需要定义一个方法,只要在需要求和时调用该方法即可,该方法将计算之后的结果返回。代码如下:

import java.util.Scanner;
public class Test {
    public static void main(String[] args) {
        Scanner input = new Scanner(System.in);
        System.out.println("请输入操作数1:");
        double num1 = input.nextDouble(); // 获取用户输入的操作数1
        System.out.println("请输入操作数2:");
        double num2 = input.nextDouble(); // 获取用户输入的操作数2
        double d = sum(num1, num2);
        System.out.println(num1 + "+" + num2 + "=" + d);
    }
    /**
     * 创建sum() 方法,返回double 类型的数值
     *
     * @param i 操作数1
     * @param j 操作数2
     * @return 两个操作数之和
     */
    public static double sum(double i, double j) {
        double sum = i + j;
        return sum;
    }
}

当用户输入两个 double 类型的数值后,程序调用 sum() 方法。该方法有两个参数,分别表示用户输入的操作数 1 和操作数 2。在调用该方法时,只需要将用户输入的两个数值传递过去即可,然后程序会执行 sum() 方法,对这两个数求和,并使用 return 语句将计算得出的结果返回。

在 main() 方法中,同样需要使用 double 类型的变量来接收 sum() 方法返回的值,即变量 d 为计算后的结果。

运行后的结果如下所示:

请输入操作数1:
500
请输入操作数2:
203
500.0+203.0=703.0
请输入操作数1:
5.66
请输入操作数2:
3.0158
5.66+3.0158=8.6758

Java break语句:跳出循环

某些时候需要在某种条件出现时强行终止循环,而不是等到循环条件为 false 时才退出循环。此时,可以使用 break 来完成这个功能。

break 用于完全结束一个循环,跳出循环体。不管是哪种循环,一旦在循环体中遇到 break,系统将完全结束该循环,开始执行循环之后的代码。

Java 中,break 语句有 3 种作用,分别是:在 switch 语句中终止一个语句序列、使用 break 语句直接强行退出循环和使用 break 语句实现 goto 的功能。

使用 break 语句直接强行退出循环(break 不带标签)

可以使用 break 语句强行退出循环,忽略循环体中的任何其他语句和循环的条件判断。在循环中遇到 break 语句时,循环被终止,在循环后面的语句重新开始。

例 1

小明参加了一个 1000 米的长跑比赛,在 100 米的跑道上,他循环地跑着,每跑一圈,剩余路程就会减少 100 米,要跑的圈数就是循环的次数。但是,在每跑完一圈时,教练会问他是否要坚持下去,如果回答 y,则继续跑,否则表示放弃。

使用 break 语句直接强行退出循环的示例如下:

public static void main(String[] args) {
    Scanner input = new Scanner(System.in); // 定义变量存储小明的回答
    String answer = ""; // 一圈100米,1000米为10圈,即为循环的次数
    for (int i = 0; i < 10; i++) {
        System.out.println("跑的是第" + (i + 1) + "圈");
        System.out.println("还能坚持吗?"); // 获取小明的回答
        answer = input.next(); // 判断小明的回答是否为y?如果不是,则放弃,跳出循环
        if (!answer.equals("y")) {
            System.out.println("放弃");
            break;
        }
        // 循环之后的代码
        System.out.println("加油!继续!");
    }
}

该程序运行后的效果如下所示:

跑的是第1圈
还能坚持吗?
y
加油!继续!
跑的是第2圈
还能坚持吗?
y
加油!继续!
跑的是第3圈
还能坚持吗?
n
放弃

尽管 for 循环被设计为从 0 执行到 10,但是当小明的回答不是 y 时,break 语句终止了程序的循环,继续执行循环体外的代码,输出“加油!继续!”。

break 语句能用于任何 Java 循环中,包括人们有意设置的无限循环。在一系列嵌套循环中使用 break 语句时,它将仅仅终止最里面的循环。例如:

public static void main(String[] args) {
    // 外循环,循环5次
    for (int i = 0; i < 5; i++) {
        System.out.print("第" + (i + 1) + "次循环:");
        // 内循环,设计为循环10次
        for (int j = 0; j < 10; j++) {
            // 判断j是否等于3,如果是,则终止循环
            if (j == 3) {
                break;
            }
            System.out.print("内循环的第" + (j + 1) + "次循环\t");
        }
        System.out.println();
    }
}

该程序运行结果如下所示:

第1次循环:内循环的第1次循环 内循环的第2次循环 内循环的第3次循环
第2次循环:内循环的第1次循环 内循环的第2次循环 内循环的第3次循环
第3次循环:内循环的第1次循环 内循环的第2次循环 内循环的第3次循环
第4次循环:内循环的第1次循环 内循环的第2次循环 内循环的第3次循环
第5次循环:内循环的第1次循环 内循环的第2次循环 内循环的第3次循环

从程序运行结果来看,在内部循环中的 break 语句仅仅终止了所在的内部循环,外部循环没有受到任何的影响。

注意:一个循环中可以有一个以上的 break 语句,但是过多的 break 语句会破坏代码结构。switch 循环语句中的 break 仅影响 switch 语句,不会影响循环。

例 2

编写一个 Java 程序,允许用户输入 6 门课程成绩,如果录入的成绩为负则跳出循环;如果录入 6 门合法成绩,则计算已有成绩之和。

使用 break 语句的实现代码如下:

public static void main(String[] args) {
    int score; // 每门课的成绩
    int sum = 0; // 成绩之和
    boolean con = true; // 记录录入的成绩是否合法
    Scanner input = new Scanner(System.in);
    System.out.println("请输入学生的姓名:");
    String name = input.next(); // 获取用户输入的姓名
    for (int i = 1; i <= 6; i++) {
        System.out.println("请输入第" + i + "门课程的成绩:");
        score = input.nextInt();// 获取用户输入的成绩
        if (score < 0) { // 判断用户输入的成绩是否为负数,如果为负数,终止循环
            con = false;
            break;
        }
        sum = sum + score; // 累加求和
    }
    if (con) {
        System.out.println(name + "的总成绩为:" + sum);
    } else {
        System.out.println("抱歉,分数录入错误,请重新录入!");
    }
}

运行程序,当用户录入的分数低于 0 时,则输出“抱歉,分数录入错误,请重新录入!”信息,否则打印学生的总成绩。输出结果如下所示。

请输入学生的姓名:
zhangpu
请输入第1门课程的成绩:
100
请输入第2门课程的成绩:
75
请输入第3门课程的成绩:
-8
抱歉,分数录入错误,请重新录入!
请输入学生的姓名:
zhangpu
请输入第1门课程的成绩:
100
请输入第2门课程的成绩:
68
请输入第3门课程的成绩:
73
请输入第4门课程的成绩:
47
请输入第5门课程的成绩:
99
请输入第6门课程的成绩:
84
zhangpu的总成绩为:471

在该程序中,当录入第 3 门课的成绩时,录入的成绩为负数,判断条件“score<0”为 true,执行“con=false”,用 con 来标记录入是否有误。接着执行 break 语句,执行完之后程序并没有继续执行条件语句后面的语句,而是直接退出 for 循环。之后执行下面的条件判断语句,判断 boolean 变量的 con 是否为 true,如果为 true,则打印总成绩;否则打印“抱歉,分数录入错误,请重新录入!”。

使用 break 语句实现 goto 的功能(break 带标签)

有时候,在嵌套很深的循环语句中会发生一些不可预料的事情。此时可能更加希望跳到嵌套的所有循环语句之外。通过添加一些额外的条件判断实现各层循环的检测很不方便。

幸运的是,Java 与 C++ 不同,Java 提供了一种带标签的 break 语句,用于跳出多重嵌套的循环语句。

break 语句可以实现 goto 的功能,并且 Java 定义了 break 语句的一种扩展形式来处理退出嵌套很深的循环这个问题。

通过使用扩展的 break 语句,可以终止执行一个或者几个任意代码块,这些代码块不必是一个循环或一个 switch 语句的一部分。同时这种扩展的 break 语句带有标签,可以明确指定从何处重新开始执行。

break 除了具有 goto 退出深层循环嵌套作用外,还保留了一些程序结构化的特性。

标签 break 语句的通用格式如下:

break label;

label 是标识代码块的标签。当执行这种形式的 break 语句时,控制权被传递出指定的代码块。被加标签的代码块必须包围 break 语句,但是它不需要直接包围 break 的块。也就是说,可以使用一个加标签的 break 语句来退出一系列的嵌套块,但是不能使用 break 语句将控制权传递到不包含 break 语句的代码块。

用标签(label)可以指定一个代码块,标签可以是任何合法有效的 Java 标识符,后跟一个冒号。加上标签的代码块可以作为 break 语句的对象,使程序在加标签的块的结尾继续执行。

下面是使用带标签的break 语句的示例。

public class GotoDemo {
    public static void main(String[] args) {
        label: for (int i = 0; i < 10; i++) {
            for (int j = 0; j < 8; j++) {
                System.out.println(j);
                if (j % 2 != 0) {
                    break label;
                }
            }
        }
    }
}

以上程序的执行结果为:

0
1

这里的 label 是标签的名称,可以为 Java 语言中任意合法的标识符。标签语句必须和循环匹配使用,使用时书写在对应的循环语句的上面,标签语句以冒号结束。如果需要中断标签语句对应的循环,可以采用 break 后面跟标签名的方式。

如在上面代码中,当 j 为 1 时,“j%2!=0”条件表达式成立,则 label 标签所代表的最外层循环终止。

注意:通常紧跟 break 之后的标签,必须在 break 所在循环的外层循环之前定义才有意义。

在 switch 语句中终止一个语句序列

在 switch 语句中终止一个语句序列,就是在每个 case 子句块的最后添加语句“break;”,这个功能在《Java switch case》已经讲过,这里不在讲述。

Java continue语句详解

有时强迫一个循环提早反复是有用的,也就是,你可能想要继续运行循环,但是要忽略这次重复剩余的循环体的语句,所以 Java 提供了 continue 语句。continue 语句是 break 语句的补充。

在上一节《Java break语句详解》中我们了解了 break,本节主要讲解 continue 语句。与 break 语句一样, 它将中断正常的控制流程。continue 语句将控制转移到最内层循环的首部。

continue 语句是跳过循环体中剩余的语句而强制执行下一次循环,其作用为结束本次循环,即跳过循环体中下面尚未执行的语句,接着进行下一次是否执行循环的判定。

continue 语句类似于 break 语句,但它只能出现在循环体中。它与 break 语句的区别在于:continue 并不是中断循环语句,而是中止当前迭代的循环,进入下一次的迭代。简单来讲,continue 是忽略循环语句的当次循环。

注意:continue 语句只能用在 while 语句、for 语句或者 foreach 语句的循环体之中,在这之外的任何地方使用它都会引起语法错误。

在循环体中使用 continue 语句有两种方式可以带有标签,也可以不带标签。语法格式如下:

continue //不带标签
continue label //带标签,label是标签名

下面看一个示例,代码如下:

int[] numbers = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
for (int i = 0; i < numbers.length; i++) {
    if (i == 3) {
        continue;
    }
    System.out.println("Count is: " + i);
}

在上述程序代码中,当条件 i==3 的时候执行 continue 语句,continue 语句会终止本次循环,循环体中 continue 之后的语句将不再执行,接着进行下次循环,所以输出结果中没有 3。程序运行结果如下:

Count is: 0
Count is: 1
Count is: 2
Count is: 4
Count is: 5
Count is: 6
Count is: 7
Count is: 8
Count is: 9

带标签的 continue 语句示例代码如下:

public static void main(String[] args) {
    label1: for (int x = 0; x < 5; x++) {
        for (int y = 5; y > 0; y--) {
            if (y == x) {
                continue label1;
            }
            System.out.println(x+","+y);
        }
    }
    System.out.println("Game Over!");
}

默认情况下,continue 只会跳出最近的内循环(代码第 3 行的 for 循环),如果要跳出代码第 2 行的外循环,可以为外循环添加一个标签 label1,然后在第 5 行的 continue 语句后面指定这个标签 label1,这样当条件满足执行 continue 语句时,程序就会跳转出外循环。

程序运行结果如下:

0,5
0,4
0,3
0,2
0,1
1,5
1,4
1,3
1,2
2,5
2,4
2,3
3,5
3,4
4,5
Game Over!

由于跳过了 x == y,因此下面的内容没有输出。

1,1
2,2
3,3
4,4

Java选择结构和循环结构的总结

任何编程语言中最常见的程序结构就是顺序结构。顺序结构就是程序从上到下逐行的执行,中间没有任何判断和跳转。

如果 main 方法的多行代码之间没有任何流程控制,则程序总是从上向下依次执行,排在前面的代码先执行,排在后面的代码后执行。这意味着:如果没有流程控制,Java 方法里的语句是一个顺序执行流,从上向下依次执行每条语句。

不论哪一种编程语言,都会提供两种基本的流程控制结构:分支结构和循环结构。分支结构用于实现根据条件来选择性地执行某段代码,循环结构则用于实现根据循环条件重复执行某段代码。

Java 同样提供了这两种流程控制结构的语法,Java 提供了 if 和 switch 两种分支语句,并提供了 while、do while 和 for 三种循环语句。一般写循环语句时,分以下三步走:

  1. 定义初始值
  2. 设置判断条件
  3. 初始值变化

除此之外,JDK5 还提供了一种新的循环:foreach 循环,能以更简单的方式来遍历集合、数组的元素。

Java 还提供了 break、continue 和 return 来控制程序的循环结构,作用如下:

  • break:表示跳出当前层循环
  • continue:表示跳出本次循环,进入下一次循环
  • return:跳出当前方法的循环

当在实现某个功能语句时,如果需要通过某一个条件去判断,则用选择结构。当实现某个功能需要通过循环去实现,则用循环结构。当然循环和选择是可以相互嵌套的。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小熊coder

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值