第三章 流程控制语句
第三章 流程控制语句
1、表达式和语句
- 语句分为单语句和复合语句
- 单语句是指,一条具体的可被执行的代码指令。比如,给变量赋值,变量相加减后赋值、调用某个方法如打印,等等。每一个单语句结束时都由分号 ; 表示结束。
- 复合语句是指,有多个单语句组成的一段代码整体,这一段代码要么都不执行,要么作为一个整体都执行,为了标识它们为一个整体,通常用 {} 将这些语句包括起来。
- 表达式
- 表达式是指可以被求值的代码,比如 1 + 2,3 * 5,a * b 等等具有值的式子被称为表达式
- 1 < 2,它的值是 true,所以 1 < 2 也是一个表达式
- 只要可以求值的式子都是表达式。
2、顺序结构
任何编程语言中最常见的程序结构就是顺序结构。顺序结构就是程序从上到下逐行地执行,中间没有任何判断和跳转。
如果 main 方法的多行代码之间没有任何流程控制,则程序总是从上向下依次执行,排在前面的代码先执行,排在后面的代码后执行。这意味着:如果没有流程控制,Java 方法里的语句是一个顺序执行流,从上向下依次执行每条语句。
3、分支语句
Java 提供了两种常见的分支控制结构:if 语句和 switch 语句,其中 if 语句使用布尔表达式或布尔值作为分支条件来进行分支控制;而 switch 语句则用于对多个整型值进行匹配,从而实现分支控制。
3.1、单分支条件判断
语法格式:
1 | if(表达式){ |
执行流程
- 首先判断条件表达式看其结果是 true 还是 false
- 如果是 true 就执行其中的代码块
- 如果是 false 就不执行代码块
在下面的示例中,我们测试两个值以确定20是否大于18。如果条件为真,则打印一些文本:
1 | if (20 > 18) { //表达式的值为 true |
3.2、双分支条件判断
当条件为 false 的时候,也可以通过使用 else 语句指定要执行的代码块。
1 | if (表达式) { |
执行流程:
在下面的例子中,time 为 20 大于 18,因此条件为 false。因此,我们将执行 else 条件,并向屏幕输出“Good evening”。如果时间小于18,程序将打印“Good day”。
1 | int time = 20; |
3.3、多分支条件判断
语法格式:
1 | if (表达式1) { |
注:多分支中,可以在 if 和 else 之中有很多个 else if
执行流程:
案例:
1 | int time = 22; |
在上面的案例中,我们按顺序判断条件,首先判断 if 中的表达式,为 false 就接着判断第一个 else if 中的表达式,也为 false 又继续判断下一个 else if ,为 true 就执行其中代码,后续就不再判断了。只要 true 出现了就不继续判断,如果 if 和所有 else if 中的表达式都为 false,则实现 else 中的代码。
3.4、if else 嵌套结构
在 if 的语句块中,或者是在else if 和 else 语句块中,又包含了另外一个条件判断(可以是单分支、双分支、多分支)。
语法结构:
1 | if (表达式1) { |
3.5、Switch…case…多分支选择结构
可以使用 switch 语句替代需要编写许多 if…else 语句的代码。
语法格式:
1 | switch(表达式) { |
注:case 后面必须是常量值,而且不能重复
执行流程:
switch 表达式求值一次。
将表达式的值与每个case的值进行比较。
如果存在匹配,则执行相关的代码块。
break 表示终止 switch 的后续匹配行为。
default 表示如没有匹配的值,则执行 default 中的代码。
案例:
1 | int day = 4; |
4、循环语句
循环语句可以在满足循环条件的情况下,反复执行某一段代码,这段被重复执行的代码被称为循环体语句,当反复执行这个循环体时,需要通过修改循环变量使得循环判断条件为 false,从而结束循环,否则循环将一直执行下去,形成死循环。
4.1、while 循环
基本语句格式:
1 | while (表达式) { |
注:while 循环中表达式必须要是 boolean 布尔类型的值
执行流程:
- 第一步:计算表达式,看表达式的值是 true,还是 false;
- 如果是 true,执行第二步;
- 如果是 false,循环语句中止,循环不再执行。
- 第二步:执行循环体语句;
- 第三步:循环体语句执行完后,重新从第一步开始再执行一遍
案例:
1 | //循环的初始化条件 |
使用while循环时,一定要保证循环条件有变成 false 的时候,比如上述代码中的 i++
,它可以一直加到等于10,是条件表达式值变为了 false,从而使循环停止,否则这个循环将成为一个死循环,永远无法结束这个循环。我们将能够使条件表达式值更新的语句称为迭代语句。
4.2、do…while 循环
do…while 循环是 while 循环的一种变体。在检查条件是否为真之前,这个循环将先执行代码块一次,然后只要条件为真,它就重复这个循环。
语法格式:
1 | do { |
注:
do{ } while( );
最后有一个分号重要区别:do…while 循环无论如何都会先执行一次循环体中的代码
执行流程:
- 第一步:执行循环体语句;
- 第二步:执行循环条件表达式,看表达式的值是 true,还是 false;
- 如果是 true,执行第三步;
- 如果是 false,循环语句终止,循环不再执行。
- 第三步:循环条件语句执行完后,重新从第一步开始再执行一遍。
案例:
1 | int i = 10; |
即使一开始 do…while 中的表达式为 false,但是还是无论如何都会执行一次循环体,使得 i = 11,从而使得表达式变为 true。
简单来说,就是先判断再执行 还是 先执行再判断的问题。
4.3、for 循环
当你确切地知道要在代码块中循环多少次时,请使用 for 循环而不是 while 循环!
语法格式:
1 | for(初始化语句; 循环条件表达式; 迭代语句){ |
注:for(;;)中的两个;不能多也不能少。
- 初始化语句 - 初始化语句在执行代码块之前执行一次,之后循环时不会再执行
- 循环条件表达式 - 每次循环检查一次条件表达式是否为 true
- 迭代语句 - 在每次循环结束时都要执行一次这个语句
执行流程:
- 执行初始化语句,完成循环变量的初始化;
- 执行循环条件表达式,看循环条件表达式的值是true,还是false;
- 如果是true,执行第三步;
- 如果是false,循环语句中止,循环不再执行。
- 执行循环体语句
- 执行迭代语句,针对循环变量重新赋值
- 根据循环变量的新值,重新从第二步开始再执行一遍
案例:
1 | // for (语句1; 语句2; 语句3){} |
语句1 在循环开始前设置一个变量( int i = 0 )。
语句2 定义了循环运行的条件( i必须小于5 )。如果条件为真,循环将重新开始,如果为假,循环将结束。
语句3 每执行一次循环中的代码块,就增加一个值 ( i++ )。
4.4、循环的嵌套
我们也可以将一个循环放入另一个循环中,这被称为嵌套循环。“内循环” 将在 “外循环” 的每次循环中执行一次:
1 | // 外循环 |
执行特点:外循环执行一次,内循环执行一轮。
4.5、break 关键字
在某些时候,我们需要在某种条件出现时强行终止循环,而不是等到循环条件为false时才退出循环。此时,可以使用break来完成这个功能。break用于完全结束一个循环,跳出循环体。不管是哪种循环,一旦在循环体中遇到break,系统将完全结束该循环,开始执行循环之后的代码。
案例:
1 | for (int i = 0; i < 10; i++) { |
这个例子会在 i 等于4时停止循环。
4.6、continue 关键字
continue的功能和break有点类似,区别是continue只是终止本次循环,接着开始下一次循环;而break则是完全终止循环本身。可以理解为continue的作用是跳过当次循环中剩下的语句,重新开始一次新的循环。例如,如下程序示范了continue的用法。
案例:
1 | for (int i = 0; i < 10; i++) { |
这个例子会在 i == 4 是提前结束,不执行后面的打印操作,直接继续开始执行 i == 5 时的循环操作。
5、变量的作用域
我们已经知道,对于复合语句我们需要用 {} 大括号将它们包括起来,{} 之中定义的变量无法在 {} 括号之外被访问,只能在 {} 之内访问。
1 | public class TestForVariableScope { |
- mainVar 和 i 变量在 main 方法这个 {} 中定义的,则在这个 main {} 中的所有地方都能访问这两个变量,而 if 和 while 语句都在 main {} 中,所以在其中也可以使用这两个变量。
- a 变量在 if 之中定义,所以在 if 的 {} 之外无法使用,而在 {} 之内的 while 语句可以使用。