详解 Java 分支与循环

分支与循环

此文章已收录至项目 Developer-Knowledge-Base

在程序设计中,顺序结构、选择结构和循环结构是三种基本的控制结构,用于组织程序代码的执行流程。

  1. 顺序结构:顺序结构是程序控制流的一种基本形式,按照代码的编写顺序逐行执行。在顺序结构中,一行代码执行完毕后,才会执行下一行代码。因此,顺序结构可以看作是一组单一的指令的集合,每个指令都按照代码中的顺序执行。

  2. 选择结构:根据条件的不同,程序会有不同的执行路径。选择结构包括 if 语句和 switch 语句。if 语句根据条件的真假来决定执行哪一条语句,switch 语句根据表达式的值来决定执行哪一条语句。

  3. 循环结构:程序会根据条件的不同,重复执行某一段代码。循环结构包括 while 循环、do-while 循环和 for 循环。while 循环会在条件为真的情况下一直执行某一段代码,do-while 循环会先执行一次代码,然后在条件为真的情况下重复执行,for 循环则是在一定次数内重复执行某一段代码。循环结构可以让程序更加灵活,可以根据需要重复执行某一段代码,从而提高程序的效率。

块作用域

在 Java 中,块作用域是指由一对花括号 {} 包含的代码块。这个块中定义的变量只能在该块内使用,并在块结束时销毁。

块是指两个大括号括起来的地方就是一个块,块中有若干 Java 语句,块确定了变量的作用域,块是可以嵌套的

所以在 Java 中,if 语句与循环语句的内部也是一个块,类是一个块,方法也是一个块

在块内部定义的变量只有在块内部才能被访问,超出块作用域后就会失效。这种机制使得程序员可以在代码块内部定义局部变量,而不必担心与程序中其他部分的变量名称发生冲突。

public class lucky {
    public static void main(String[] args) {
        int i = 0; { //大括号
            int a = i + 9; //这就是一个块,可以使用外一层的变量 i
        } //大括号结束
    }
}

一个块中定义的变量拥有块作用域,在内部块定义的变量在外部不能用。但在外层块定义的变量在内层块可以使用

和 c 语言不同的是,Java 中外层块中定义的变量与内层块中的相同,在 c 语言中相同名字的变量内层块中的变量作用域会覆盖外层块中的变量作用域,但在 Java 中不能这么做

但如果是内部块在先,执行完内部块后,在后面再定义之前在块中定义变量相同的变量名,是可以的

public class lucky {
    public static void main(String[] args) {
        int i = 0;
        int b = 3; {
            int a = 9;
            int c = i + a; //可以使用外部块中的变量
            //int b = 3;   //不能与外部变量同名
        }
        int a = 0; //内部块作用域结束,不影响外部块了
        System.out.println(a);
        //System.out.println(c);   //错误,不能使用内部块中的变量
    }
}

尽管块作用域结束后可以使用块内变量名,但还是尽量不要使用相同变量名

选择结构

if-else

格式为

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

这是最简单的 if 条件表达式,当条件表达式为真,则执行语句块,若条件表达式为假,则直接跳过语句块执行之后的语句。

条件表达式可以是逻辑表达式,也可以是单纯的布尔值

若是不为真想执行另外一些语句呢?有 else

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

当条件表达式为真时执行语句块 1,若是条件表达式为假时,则执行 else 里的语句块,也就是语句块 2

若还想提供多个分支,一个判断不够

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

当 if 之后的条件表达式不成立后,就一条一条判断之后的 else if 后面的表达式,若 else if 后面的条件表达式中有为真的,就执行相应代码块,若都为假,就执行 else 后的语句块,若全部都为真,也只会执行最先判断到为真的

else 语句一般放到最后,表示,以上条件表达式都不为真时要执行的

当 if 或者 else 只有一条语句时,大括号可以省略,但这样会使结构不清晰,所以最好不要这样做

import java.util.Scanner;

public class lucky {
    public static void main(String[] args) {
        Scanner input = new Scanner(System.in);
        System.out.println("你有多少万存款?");
        int i = input.nextInt();
        if (i >= 500) {
            System.out.println("凯迪拉克");
        } else if (i > 100) {
            System.out.println("帕萨特");
        } else if (i > 50) {
            System.out.println("伊兰特");
        } else if (i > 10) {
            System.out.println("奥托");
        } else {
            System.out.println("捷安特");
        }
    }
}

选择结构是可以嵌套的

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

这里有很重要的一点,else 只会与最近的 else 相匹配

在以下这种情况,与 else 匹配是属于内部的 if 的,所以最好不要省大括号

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

switch case 语句

分支结构还有另外一种表示语句,那就是 switch case 语句
这种结构可以解决分支太多的情况

基本语法

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

switch 语句先计算括号内的值,再依次寻找 case 后是否有与之计算结果相匹配的值,如果找到了则执行该 case 后的语句块,然后执行 break,跳出 switch 语句,但如果 case 后面都没有与之匹配的值,那么就执行 default 语句后的语句

case 后面的值可以是字符常量与整型常量,在 jdk7 之后支持字符串常量,不可以是变量,case 与值用空格隔开,值后要加冒号,每个 case 后的值都是唯一的,不能与其他 case 后的值重复

break 语句也可以省略,省略后会执行完该 case 语句后会再执行下一条 case 语句,因为没有跳出语句,它就就会像顺序结构一样一条条 b 执行语句,直到遇见 break 或语句结束

int i = 14;
switch (i) {
    case 14:
        System.out.println("这个值是 14");
    case 15:
        System.out.println("这个值是 15");
    case 16:
        System.out.println("这个值是 16");
    default:
        System.out.println("这里没有要找的值");
        break;
}

执行结果:
这个值是 14
这个值是 15
这个值是 16
这里没有要找的值

default 语句可以放在 switch 语句的任何位置,运行结果没有改变,如果 default 语句在 switch 语句块的最后,后面的 break 可以省略,如果在中间或者最前面的话,break 是不能省略的,因为如果在中间没有了 break,执行完 default 后还会执行之后的 case 语句

if else 与 switch case 的区别

if else 和 switch case 都是 Java 中的条件语句,它们的作用是根据条件判断程序该执行哪段代码。它们的区别主要有以下几个方面:

  1. 适用场景不同
    if else 适用于只有几个条件需要判断的情况,而 switch case 适用于有多个条件需要判断的情况。如果只有两个条件需要判断,使用 if else 和 switch case 效果相当,但是如果有多个条件需要判断,使用 switch case 会比 if else 更加清晰、简洁。

  2. 条件表达式的类型不同
    if else 可以判断任何类型的条件表达式,而 switch case 只能判断整型、枚举类型或者字符串类型的表达式。

  3. 执行效率不同
    if else 语句执行效率比 switch case 语句要高,原因是 switch case 语句在执行时需要进行多次比较,而 if else 语句只需要进行一次比较。

  4. 代码结构不同
    if else 语句比较灵活,可以根据具体情况编写不同的代码结构,而 switch case 语句的代码结构比较固定,每个 case 分支需要以 break 结束。

综上所述,if else 和 switch case 在使用时需要根据具体情况选择合适的条件语句。如果只有几个条件需要判断,或者需要判断的条件类型比较复杂,建议使用 if else。如果需要判断的条件较多,且条件类型比较简单,建议使用 switch case。

循环结构

如果想重复执行一段代码直到满足条件,可以使用循环,几乎所有流行的编程语言都又循环

while 循环

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

基本语法

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

while 循环的执行过程是,当执行到 while 语句块时,先判断括号内的条件表达式是否为 true,如果为 true 则执行语句块,执行完语句块后再回到最初,判断括号内条件表达式是否为 true,一直运行,直到条件表达式为 false

值得注意的是:
while 循环是先判断条件表达式再执行代码块的
在 while 循环内一定要设置改变条件的语句,不然就成了死循环,一直不会退出循环,除非强制停止程序
在 while 的括号后面不能加分号,否则就是一个死循环

使用循环输出 100、95、90、85、…、5

public class lucky {
    public static void main(String[] args) {
        int i = 100;
        while (i > 0) {
            System.out.print(i + "、");
            i = i - 5;
        }
    }
}

输出:100、95、90、85、80、75、70、65、60、55、50、45、40、35、30、25、20、15、10、5、

今有鸡兔同笼,上有三十五头,下有九十四足,问鸡兔各几只?试编写程序解决这个问题。

public class lucky {
    public static void main(String[] args) {
        int x = 35;
        int y = 0;
        while (true) {
            if (x * 2 + y * 4 == 94){
                break;
            }
            x--;
            y++;
        }
        System.out.println("鸡有" + x + "只,兔有" + y + "只");
    }
}

do while 循环

使用 while 循环是首先检查条件表达式的,里面的代码可能一次都不执行,但 do while 语句就解决了这种问题,它与 while 最大的区别就是 do while 一定会执行循环体里面的语句至少一次

语法:

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

例子:

public class lucky {
    public static void main(String[] args) {
        Scanner input = new Scanner(System.in);
        int i;
        do {
            System.out.println("请输入十以内的数字继续循环,输入超过十的数字结束循环");
            i = input.nextInt();
        } while (i < 10);
        System.out.println("结束循环");
    }
}

例子中先提示,后输入,输入后判断输入的是否是十以内的数,如果是就继续循环,如果不是就结束循环

前面我们提到,变量的定义尽量在离第一次使用这个变量最近的地方,那为什么 9 不定义在 do while 中呢,因为 do while 语句也是一个作用域,两个大括号括起来的地方就形成了一个区域,在里面定义的变量只有在那里面可以用,但我们判断的时候使用了,如果定义在里面,就会报错

for 循环

for 语句可以看做 while 的简化版,它把初始化,条件,以及迭代语句整合在了括号中,以至于不会忘记设置

注意:while 语句可以实现的 for 都可以实现,for 可以实现的,while 一样也可以实现,也就是说,循环之间都是可以转换与嵌套

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

条件表达式 1: 一般用做参数初始化,例如变量定义 例如 int i=10
条件表达式 2: 是循环的判断条件,就是 while 括号里面的那部分 例如 i<20
条件表达式 3: 一般作为迭代语句,改变判断条件里面那个变量 例如 i++ i–

执行顺序:
先执行条件表达式 1,然后判断条件表达式 2 是否为 true,如果为 false 则之间跳过循环体语句块和条件表达式 3,直接执行 for 语句下面的语句,若条件表达式 2 为 true,则执行循环体语句块
执行完语句块后再执行条件表达式 3,执行完后再去判断条件表达式 2,若为 true 则继续执行语句块然后又执行条件表达式 3 直到条件表达式 2 为 false

例子:

for (int i = 0; i < 100; i++) {
    System.out.println(i);
}

这段代码用于输出从 0 到 100 的数字,先初始化变量 i,判断 i 是否小于 100,然后输出 i,再然后执行 i++,再去判断 i 是否小于 100,直到 i 不小于 100

注意:在这里变量 i 也是局部变量,只能在 for 循环中使用

输出九九乘法表示例

for (int i = 1; i < 10; i++) {
    for (int j = 1; j < 10; j++) {
        if (j <= i)
            System.out.print(i + "*" + j + "=" + i * j + "  ");
    }
    System.out.println();
}

for 循环中的三个条件表达式都是可以省略的,但是中间的分号不能省略,否则就是语法错误

省略第一个条件表达式:进入循环中首先执行的语句,这条语句也可以放在 for 语句之前

省略第二个条件表达式:省略后需要使用 break 语句跳出循环,不然会形成死循环,省略了判断条件将默认为真

省略第三个条件表达式:省略后少了改变条件的语句,也是可以在循环体中加,如果不加也容易造成死循环

三个条件表达式都省略:除非有 break 语句结束循环,否则是一个循环

循环控制语句 break 与 continue

为了更好地控制循环走向,java 与其他高级编程语言一样,有 break 与 continue 两种循环控制语句,但 Java 的 break 语句与其他编程语言的稍有不同

break

break 在英文中是中断的意思,而事实也是如此,之前说到 switch 中的语句 break 可以跳出 switch 语句块,循环中的作用也差不多,就是中断循环,不让循环继续下去,在循环体中 break 之后的语句都不会执行

while (true) {
    break;
    System.out.println("这条语句不会执行")
}

break 语句一般搭配 if 语句一起使用

int i = 0;
while (i < 10) {
    if (i > 5){
        break;        
    }
    System.out.println(i);
    i++;
}

这条语句将 0 到 5 输出,因为 i 加到 6 时满足 if 条件,执行了 break 语句,之间跳出循环了,虽然 i 等于 6,但是因为在输出之前就已经跳出了循环,所以 break 之后的语句不会执行;

break 语句还可以除了可以跳出 switch 与循环外,还可以跳出指定循环与语句块

如果有多重循环嵌套,想跳出的是外层循环,可以用 break 加标签来实现,这点和 c 语言不同,c 语言是只能跳出此层循环,因为 c 语言的跳转可以用 goto 语句实现,而 goto 在 java 里被作为了保留字,没有跳转功能

a: for (int i = 0; i < 10; i++) {
    for (int j = 0; i < 10; j++) {
        if (i == 2)
            break a;
        System.out.println("钟舒艺")
    }
}

该实例使用 if 语句加 break 直接跳出外层循环,当跳出后,不会执行里面的任何东西了,直接执行循环之后的语句

break 还可以用来跳出语句块,实现了部分 goto 的功能;

be: {
    int i = 11;
    System.out.println("跳出语句块");
    if (i > 10)
        break be;
    System.out.println("这段跳出后不执行");
}

其实跳出循环也属于跳出语句块,循环本身就是一个语句块,使用 break 跳出语句块后,这个 break 之后的语句都不会执行了。同理,if 也是语句块,也可以用 break 跳出,当然,你得在语句块前面加一个标签,标签后面一定要一个冒号

但是这种方法在实际中并不常用

continue

当满足条件后既想跳过在这之后循环体语句,又不想退出这个循环,要继续循环,这个时候可以用 continue 语句

continue 在英文中是继续的意思,在 Java 中表示即刻开始下一次循环

for (int i = 0; i < 10; i++) {
    if (i % 2 == 0)
        continue;
    System.out.print(i + ",")
}

输出结果为 1,3,5,7,9

此示例的意思是,当 i 为偶数时,直接进行下一次循环,而忽略了循环里面 continue 之后的语句,执行完 continue 后直接跳到 for 语句的表达式 3,然后判断表达式 2,从而忽略了System.out.print(i+",")

在 for 循环中使用 continue 会执行迭代语句,也就是表达式 3,但在其他循环中需要注意,不要把迭代语句放到 continue 之后去,这样可能也会造成死循环

例如:

 int i = 0;
while (i < 10) {
    System.out.println("钟舒艺");
    if (i == 9)
        continue;
    i++;
}

注意点

  1. 循环与选择都可以多层嵌套,理论上可以无限嵌套
  2. while 循环与 do while 循环注意加迭代语句,否则可能造成死循环
  3. for 语句三个表达式都可以省略,但是两个分号是不能省略的
  4. break 可以跳出 switch 语句,循环,以及语句块,但跳出外层循环或跳出语句块时要配合标签使用
  5. continue 可以即刻开始下一次循环,所以在 while 或者 do while 中不要把迭代语句放在 continue 之后
  6. 在选择与循环中声明的变量属于局部变量,只能在该语句块中使用

在循环中还有一个需要注意的地方就是,尽量不要检测两个浮点数是否相等
例如:

for (double x = 0; x != 10; x += 0.1)
这个语句可能会是一个死循环 ,由于 0.1 无法用二进制精确的表示,所以,x 将从 9.999 999 999 999 98 跳到 10.099 999 999 999 98

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值