前言
和其他程序设计语言一样,Java使用条件语句和循环结构确定控制流程,在介绍这些条件语句和循环结构之前,我们先来了解一下块作用域这个概念。
块作用域
块(block,即复合语句)是指由一对大括号括起来的若干条简单的Java语句,块确定了变量的作用域。一个块可以嵌套在另一个块中。下面是在main方法块中嵌套另一个语句块的实例:
public static void main(String[] args) {
int n;
...
{
int k;
}
//变量k在此处无法使用
}
但是,不能在嵌套的两个块中声明同名的变量。比如:
public static void main(String[] args) {
int n;
...
{
int k;
int n; //错误,不能在这里定义n
}
}
条件语句
在Java中,条件语句的格式为
if (condition) statement
这里的条件必须用括号括起来。
在Java中,我们通常需要在条件为真的时候执行多条语句,在这种情况下,就需要使用到我们前面说到的块语句。条件语句格式变成如下:
if (condition) {
statement1
statement2
}
有时,我们需要在条件为真的时候执行一组语句,当这个条件为假的时候,执行另一种语句,这是需要用到else。于是条件语句的更一般的写法变为:
if (condition) {
statement1
statement2
} else {
statement3
statement4
}
这里需要一点的是,else子句与最邻近的if构成一组,比如:
if (x <= 0) if (x == 0) sign = 0; else sign = -1
当然,这种写法在我们日常中很少见到,但是我们要知道这里的else是与第二个if配对的。写成如下就会显得很清晰:
if (x <= 0) {
if (x == 0) {
sign = 0;
} else {
sign = -1;
}
}
这里就体现了大括号和缩进的合理使用对于代码可读性的重要性。
while循环
当条件为true的时候,while循环执行一条语句(或者一个语句块)。一般格式为:
while (condition) {
statement
...
}
当然,如果开始循环的时候条件就是false的话,该循环是一次也不会执行的。也正是因为while循环语句首先检测循环条件。因此,循环体中的代码有可能不被执行。如果希望循环体至少执行一次,应该把检测条件放到最后,这时我们的do...while语句就派上了用场,它的基本格式如下:
do statement while (condition);
for循环
for循环语句是支持迭代的一种通用结构,利用每次迭代之后更新的计数器或者类似的变量来控制迭代次数。for语句的第1部分通常用于对计数器进行初始化,第2部分给出每次新一轮循环执行前要检测的循环条件,第3部分指示如何更新计数器。
与C++一样,尽管Java允许在for循环的各个部分放置任何表达式,但是有一个不成文的约定俗成的规则:for语句的三个部分应该对同一个计数器变量进行初始化,检测和更新。
这里需要注意一点,当你使用浮点数作为计数器时,很可能会出现一些奇奇怪怪的BUG,例如:
for (double x = 0; x != 10; x += 0.1)
这个循环永远也不会结束,由于舍入的误差,最终可能得不到精确值。例如,在上面的循环中,因为0.1无法用二进制精确的表示,所以,x将从9.9999999999998跳到10.0999999999998。
当在for语句的第1部分中声明了一个变量之后,这个变量的作用域就为for循环的整个循环体,如果在for语句中定义一个变量,这个变量就不能在循环体外使用。如果需要使用循环体中的变量数据,需要提前在循环外进行定义。
增强for循环
Java有一种功能很强的循环结构,可以用来依次处理数组中的每一个元素而不必为指定下标值分心。
这种增强的for循环的语句格式为:
for (variable : collection) {
statement
}
定义一个变量用于暂存集合中的每一个元素,并执行相应的语句(或语句块)。collection这一集合表达式必须是一个数组或者是一个实现了Iterable接口的类对象(比如ArrayList)。当然,实践中我们发现,增强for循环虽然简洁,但是无论是应用场景还是运行速率上来说,都是不如传统的for循环的。只是为我们程序员编码提供了一种更加简洁的方式~
多重选择:switch语句
在处理多个选项的时候,使用if/else就会略显笨拙,这时switch语句就发挥了他应有的作用,如下所示:
switch (choice) {
case '1':
...
break;
case '2':
...
break;
default:
...
break;
}
switch语句将从与选项值相匹配的case标签处开始执行直到遇到break语句,或者执行到switch语句的结束处为止。如果没有相匹配的case标签,而有default子句,就执行这个子句。如果在case分支语句的末尾没有break语句,那么就会接着执行下一个case分支语句。这种情况称之为case穿透,一般来说,我们不希望看到这种情况的出现,所以,为了程序的安全起见,若不是非常必要的情况下,不要使用switch语句。
case标签可以是:
- 类型为char,byte,short或int的常量表达式
- 枚举常量
- 如果你的JDK版本是1.7以上,他还可以是字符串字面量
中断控制流程语句
我们在使用的过程中,如果遇到需要中断一个流程的情况,通常会使用到以下两个关键字:break和continue,虽然goto是Java的保留字,但是我希望永远不要出现在Java中,无休止的使用goto会将一个程序弄得非常糟糕,无法阅读。
break 主要用在循环语句或者 switch 语句中,用来跳出整个语句块。break 跳出最里层的循环,并且继续执行该循环下面的语句。当然我们也可以使用标签的方式来跳出某个指定的循环。
read_data:
while(...) {
for(...) {
break read_data; //这里就是直接跳出了while循环
}
}
continue 适用于任何循环控制结构中。作用是让程序立刻跳转到下一次循环的迭代。在 for 循环中,continue 语句使程序立即跳转到更新语句。在 while 或者 do…while 循环中,程序立即跳转到布尔表达式的判断语句。当然,continue也有一种带标签的形式,将跳到与标签匹配的循环首部。用法和break一样,这里就不再举例说明。
网友评论