java流程控制

本文详细介绍了JAVA中的分支控制结构,包括if条件语句和switch语句,以及条件语句的逻辑错误避免方法。同时,讨论了循环控制结构,如while、dowhile和for循环,以及break和continue语句的使用。文章还提到了在多层循环中如何利用标签配合break和continue实现精确控制。
摘要由CSDN通过智能技术生成



JAVA就3种基本结构:顺序结构、选择结构、循环结构
顺序结构就是从上往下依次执行,下面分别介绍选择结构和循环结构。


分支控制结构

JAVA提供了2种分支控制结构:if语句和switch语句

if条件语句

if语句由条件语句条件执行体组成。

条件语句的括号里面是一个布尔值。

条件执行体会作为一个代码块用{}括起来,需要把它当做一个整体。从{}外部看,就等价于一个单独的语句。如果没有break、continue、return等关键词或者遇到异常,进入条件执行体后,会把内部的所有代码执行完。

根据条件语句布尔值的真假来决定执行哪部分的条件执行体。

if语句有3种形式

形式1:
if (logic expression) {
statement…
}

形式2:
if (logic expression) {
statement…
} else {
statement…
}

形式3:

if (logic expression) {
statement…
} else if (logic expression) {
statement…
}
// else if语句可以有多个
else {
statement…
}

如果条件执行体只是一条语句,可以省略掉{},但是为了程序可读性,最好不要省略花括号

其实条件语句非常好理解,只要牢牢记住被{}括起来的条件执行体在外部相当于一条语句,然后根据条件表达式的真假决定进入哪一部分条件执行体就行了。

条件语句的常见逻辑错误

条件语句本身很简单,比较容易出现的逻辑错误在于条件的划分出了问题,没有做到不重不漏的划分成立范围。
比如,a > 60, a > 40, a > 20 这3个条件其实就有重叠部分。
你可以写成:
if (a > 60) {
statement…
} else if (a > 40) { // 因为else本身就包含a <= 60的意思,所以实际这句条件等价于a > 40 && a <= 60
statement…
} else if (a > 20) {
statement…
} else { // 这句相当于a <= 20,如果省略掉,相当于a <= 20的时候,程序不做任何行为
statement…
}
这样做就相当于把条件分成4个范围:(60,正无穷)、(40,60]、(20,40]、(负无穷,20],这就做到了不重不漏。

简单说,只需把范围更小的条件写在更前面,这样后面写更大范围的条件时,通过else把前面的小范围条件去掉了,就做到不重不漏了。

与之相关的,有时候有的语句需要在多个条件同时成立时运行
比如:

	if (x % 3 == 0 && x % 5 == 0) {
		System.out.println("乒乓");
	} else if (x % 3 == 0) {
		System.out.println("乒");
	} else if (x % 5 == 0) {
		System.out.println("乓");
	} else {
		System.out.println(x);
	}

这段代码的第一个条件语句,需要同时满足x能整除3和5。
这其实就是上面讲解的范围更小的语句,需要放到最上面。那之后的语句就排除掉x同时能整除3和5的情况。

第二个条件相当于x % 3 == 0 && x % 5 != 0;
第三个条件相当于x能整除5不能整除3。



switch语句


switch语句的格式
switch(expression) {
case condition1 :
statement…
break;
case condition2 :
statement…
break;

case conditonN:
statement…
break;
default:
statement…
}
switch语句会先计算控制表达式expression的值,然后在下面的case标签里面寻找相同的值,也就是condition1~conditioN的值里面寻找相等的值。作为后续程序的入口
break语句是switch语句的出口。如果没有break语句,程序会从入口处不断向下执行。假如conditioni和expression的值匹配,那入口就是conditioni,程序会执行conditioni~conditionN部分的所有代码,也包括default部分的代码,直到执行到switch语句的末尾。

所以,switch语句其实很好理解:程序根据expression的值寻找程序入口。和expresion匹配的conditoni就是程序的入口而之后的break语句就是程序的出口如果没有break语句,就会执行到整个switch语句结束

default语句可以省略,default的作用是假如所有case标签都无法和控制表达式的值匹配,程序就直接跳转到default语句部分执行

switch语句注意事项


除了break语句是程序出口这点外,控制表达式expression的数据类型是很容易忽略的点。
switch语句只支持6种数据类型:byte、short、char、int、枚举、String
其实很好记忆,前面4种都是整型类型,long之所以不支持可能是因为没有对很大的整数值进行匹配的需求。
枚举类型本身也是类似基本整数类型的用法。
String类型是后面新加入的功能,是为了进行字符串的匹配。

同时,switch语句只能匹配相等的值,不能对一个条件范围进行匹配
控制表达式expression的计算结果是整型或者枚举类型或者字符串的值,不能是一个布尔值,不能写x < 5之类的表达式。case标签的condition部分,只能写相同类型的字面量,不能写类似 x < 8之类的范围进行匹配。

如果要根据不同的范围决定进入哪个分支,应该使用if else if条件语句



循环控制结构

JAVA提供了4种循环控制结构:while、do while、for、foreach循环

循环语句可以抽象出4个组成部分:
1.初始化语句:在循环开始前执行,会提前做一些初始化的工作。
2.循环条件:一个boolean表达式,如果为真就继续循环,如果为假就结束循环。
3.循环体:循环的主体,在条件为真时,循环体会不断被执行。
4.迭代语句:这是循环最容易出错的地方,必须要在每次循环结束前改变控制循环条件的变量,让循环能在合适的时候结束。

while循环

while循环的通用语法格式为:
[init statements;]
while (test_expression) {
[statements;]
[interation_statements;]
}

当循环条件为真,就会执行整个循环体直到结束,然后再进行下一次判断,不断循环下去,直到循环条件为假。

和if语句类似的是,花括号里的循环体,在外部看来,就是一行语句如果循环体就一行语句,也可以省略花括号,但是这种做法会降低可读性
一个常见的相关错误是:
while(test_expression);
{
执行语句
}
在循环条件后面多了一个分号,它相当于一个空语句,这就相当于只有一行语句,所以省略了花括号,循环会不断执行空语句,无法结束循环。花括号后面的代码已经和while循环无关了。

do while循环

do while循环的通用语法格式为:
[init statements;]
do
{
[statements;]
[interation_statements;]
}while (test_expression);

和while语句不同的是,do while语句是先执行循环体,然后进行循环条件的判断
这种细微的差别会导致do while循环无论如何都会执行至少一次循环体,但是while循环可能在第一次判断就会假,循环体一次不执行,直接结束整个循环。

分析可以发现,while循环的循环条件会执行n+1次,循环体会执行n次。
而do while循环的循环条件和循环体会执行n次。

所以,可以把do while循环理解为少执行一次循环条件判断的while循环。

for循环

for循环的通用语法格式为:
for(init statement; test_expression; interation_statement)
{
[statements;]
}

for循环很清晰的呈现了循环的4个组成部分。
第一个括号里面包含了3部分:初始化语句循环条件迭代语句
分别介绍for循环4个部分的执行方式:
1.初始化语句:初始化语句会在for循环开始前执行一次,之后再也不执行。
2.循环条件:每次执行循环体之前,会先判断循环条件,如果为真才继续执行。这一点看,for循环和while循环是可以互相转换的。
3.循环体:当判断完循环条件后,会立刻执行循环体部分,执行循环体会先于执行迭代语句
4.迭代语句:在每次循环最后,会执行迭代语句,让循环条件最终能在合适的时间结束。

分析可以发现,for循环和while循环非常像,while循环和for循环是可以互相转换的。
for循环的4个部分结构更清晰,程序可读性更好,但是代码会稍微复杂一些。

for循环的注意事项

1.和while循环有很大不同的是:for循环的迭代语句不在循环体里面如果使用continue结束本轮循环,for循环的迭代语句还是会被执行的
在while循环里,如果迭代语句在continue之后,迭代语句就会被跳过,这就会导致死循环
所以,使用while循环配合continue语句时,一定要注意将迭代语句放到continue语句之前

2.因为for循环已经清晰划分了循环的4个部分,所以不要把迭代语句写到for循环的循环体里面,这样会降低可读性。

3.for循环的初始化语句部分,可以一次初始化多个相同类型的变量,例如:for( int i = 0, j = 0, k = 0; …; …)
注意,初始化语句只能初始化相同类型的多个变量,不能初始化多个类型的变量。这样是不合规的: for( int i = 0, double j = 0; …; …)
因为大部分需要初始化的变量都是整型变量,所以for循环可以应对绝大部分情况。
如果真有及其特殊的情况,需要初始化不同类型的变量,那就使用while循环即可。

4.迭代语句可以写多条语句,中间用逗号(,)连接。比如很常见的:for(int i = 0, j = 0;… ;i++, j++)

5.for循环括号内的三个部分都是可以省略的,只需要保留两个分号(;)即可。比如省略第一和第三部分的for循环就类似while循环:
for(;test_expression;)
{
}

循环控制语句

java有2个关键字用于循环控制:continue和break
这两种控制循环的语句其实很好理解。
break:结束当前的整个循环语句
continue:结束本轮循环体的执行
这两个控制语句都是希望在满足某个条件时执行循环的控制,所以它们一定会搭配条件语句一起使用。

break语句

如果希望程序在某种条件出现时,就强行终止当前整个循环,就使用break语句。
这个语句其实非常常用,因为如果没有break语句,循环必须要通过循环条件判断为false才能跳出当前循环。但是,循环条件的判断必须要执行上一轮整个循环体后,才能进行判断。很多时候,我们需要程序在循环体的中间,满足某个条件时,就立刻跳出循环,这时候就需要用到break了

break语句配合标签

注意:break语句只能结束所在的当前循环。如果是嵌套循环,必须在break后紧跟标签才能做到。
标签是成对出现的。第一个标签必须写在想跳出的外层循环的代码之前(这里强调,必须是外层循环代码前,而不是后,不要和C++的goto语句搞混了),第二个标签写在break关键词之后。
通用格式是:
tag:
外层循环头
外层循环体内有:break tag;

第一个标签后要加一个冒号(😃,第二个标签要在break语句后,意思是,break语句会直接结束第一个标签标记的外层循环,从而实现一次跳出多层循环的作用。

public class ForTest {
    public static void main(String[] args) {
        outer:
        for(int i = 0; i < 3; i++) {
            for (int j = 0; j < 5; j++) {
                if (j == 3) {
                    break outer;
                }
                System.out.println("i = " + i + ", j = " + j);
            }
        }
    }
}

这段代码的输出结果为:
i = 0, j = 0
i = 0, j = 1
i = 0, j = 2

因为每次当j = 3时,就直接结束外层循环,外层循环后又没有多余代码,所以程序直接就终止了。

continue语句

只要搞懂了break语句,同时能区分continue语句和break语句的区别,continue语句就自然掌握了。
其实很简单,continue语句是结束本次循环体,相当于直接跳转到循环体末尾,重新执行下一次循环体
所以,continue语句常用来跳过一些不想执行的特殊结果,只是跳过单次循环体,后续还是希望继续循环下去的。

continue语句配合标签

continue语句也有标签,也是为了跳过多层循环。只是跳过多层循环的这一轮,后续还会继续进行多层循环的执行。
比如之前的例子改成continue的话:

public class ForTest {
    public static void main(String[] args) {
        outer:
        for(int i = 0; i < 3; i++) {
            for (int j = 0; j < 5; j++) {
                if (j == 3) {
                    continue outer;
                }
                System.out.println("i = " + i + ", j = " + j);
            }
        }
    }
}

最终结果为:
i = 0, j = 0
i = 0, j = 1
i = 0, j = 2
i = 1, j = 0
i = 1, j = 1
i = 1, j = 2
i = 2, j = 0
i = 2, j = 1
i = 2, j = 2

这里程序到j = 3时,就直接跳过2层循环,但是循环还要继续,所以之后i的值会递增,然后继续输出新的结果。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值