天天看点

Java核心卷 卷一 自我笔记 3.5Java的基本程序设计结构---控制流程

条件语句

在Java中,条件语句的格式为

if(condition)statement

这里的条件必须用括号括起来。与绝大多数程序设计语言一样,Java常常希望在某个条件为真时执行多条语句。在这样的情况下,应该使用块语句,例如:

if(a>=b){
            System.out.println(a);
        }
           

另外,我们需要介绍一下代码块。什么是代码块?

块,是指由一对大括号括起来的若干条简单的java语句。块确定了变量的作用域。一个块可以嵌套到另一个块中。需要注意的是,不能在嵌套的两个块中声明同名的变量。

在Java中,if经常和else搭配。例如:

if(a>=b){
            System.out.println(a);
        }else{
            System.out.println(b);
        }
           

其中else部分是可选的。else子句与最邻近的if构成一组。

重复出现if…else…是一个很正常的情况。需要注意的是,else是与哪一个if配对。

多重选择

在处理多个选项时,使用if/else结构显得有些笨重。Java中用一个与C语言完全一样的switch语句。

例如,我们建立一个包含4个选项的菜单系统。

public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        System.out.println("select an option on (1,2,3,4)");
        int i = in.nextInt();
        switch (i){
            case 1:
                System.out.println(i);
                break;
            case 2:
                System.out.println(i);
                break;
            case 3:
                System.out.println(i);
                break;
            case 4:
                System.out.println(i);
                break;
            default:
                System.out.println("无");
                break;
        }
    }
           

switc语句将从与选项值相匹配的case标签处开始执行直到遇到break语句,或者执行到switch语句的结束处为止。如果没有匹配的case标签,那么,执行default子句。

需要我们注意的是,我们在编程序的时候,可能会触发多个case分支。如果在case分支语句的末尾没有break语句,那就会接着执行下一个case分支语句。这种情况相当危险,常常引发错误。所以,我们在程序中尽量少用switch语句。

case的标签可以是:

  • 类型为char、byte、short或int的常量表达式。
  • 枚举常量(当在switch语句中使用枚举常量时,不必再每个标签中指明枚举名,可以有switch的表达式值确定)
  • 从Java se 7开始,case标签还可以是字符串字面量

循环

1. while循环

当条件为真(true)时,while循环执行一条语句(也可以是一个语句块)。格式为:

while(condition)statement

如果开始条件为flase,那么一次也不执行。

我们以一个例子来说明,该程序是计算需要多长时间才能存够一定的退休金。

public class RetirementTest {
    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        System.out.println("how much money do you need to retire?");
        double v = in.nextDouble();
        System.out.println("how much money will you contribute every year?");
        double v1 = in.nextDouble();
        System.out.println("interest rate in %:");
        double v2 = in.nextDouble();
        double balance=0;
        int years=0;
        while (balance<v){
            balance+=v1;
            double interest= balance*(v2/100);
            balance+=interest;
            System.out.println(balance);
            years++;
        }
        System.out.println("you can retire in"+years+" years.");
    }
}
           

在这个例子中,我们的循环是一个计数器,在循环体中更新当前累积的数量,直到条件为false为止。

while (balance<v){
            balance+=v1;
            double interest= balance*(v2/100);
            balance+=interest;
            System.out.println(balance);
            years++;
        }
           

while循环语句首先检测循环条件。因此,循环体中的代码有可能不被执行。如果希望循环体至少执行一次,那么,应该将检测条件放到最后。使用do while循环。

2. do while循环

语法格式为:

do statement while (condition)

这种循环先执行语句(通常是一个语句块),再检测循环条件;然后重复语句,依次类推。例如:

do {
            balance+=v1;
            double interest= balance*(v2/100);
            balance+=interest;
            System.out.println(balance);
            years++;
        }
        while (balance < v);
           

3. for 循环

for循环是支持迭代的一种通用结构,利用每次迭代之后更新的计数器或类似的变量来控制迭代次数。

下面的程序将0~9输出到屏幕上:

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

for循环的第一部分通常用于对计数器进行初始化;第二部分给出新一轮循环执行前要检测的循环条件;第三部分指示如何更新计数器。我们需要知道的是Java允许在for循环的各个部分放置任何表达式,但有一条不成文的规则:for语句的3个部分应该对同一个变量进行初始化、检测和更新。

我们要注意的是,在循环中检测两个浮点数是否相等需要格外小心。如下面的for循环

for (double x = 0; x !=10 ; x+=0.1) {
            System.out.println(x);
        }
           

永远不会结束。由于舍入的误差,最终可能得不到精确值。例如,在上面的循环中,因为0.1无法精确用二进制表示,所以x将从9.99999999998跳到10.0999999998.

我们在for语句的第一部分中声明了一个变量之后,这个变量的作用域就为for循环的这个循环体。

特别需要指出的是,如果在for语句内部定义一个变量,这个变量就不能在循环体之外使用。因此,如果希望在for循环体之外使用循环计数器的最终值,就要确保这个变量在for循环外声明。

int x;
        for (x = 0; x !=10 ; x+=0.1) {
            System.out.println(x);
        }
           

另一方面,我们可以在各自独立的不同for循环中定义同名的变量。即,不同的for循环计数器的命名可以相同。

除此之外,for循环语句只不过是while循环的一种简化形式。

我们以下面的程序作为应用for循环的一个例子。

public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        System.out.println("how many number do you need to draw?");
        int i = in.nextInt();
        System.out.println("what is the highest number you can draw?");
        int i1 = in.nextInt();
        int c=1;
        for (int j = 1; j <= i; j++) {
            c=c*(i1-j+1)/j;
            System.out.println("your odds are 1 in "+c+" . good luck!");
        }
    }
           

这个程序是用来计算抽奖概率。

在Java中有一种功能很强的循环结构,可以用来依次处理数组中的每一个元素而不必为指定下标值而分心。这种增强的for循环的语句格式为:

for(vatiable :collection)statement

定义一个变量用于暂存集合中的每一个元素,并执行相应的语句。

例如:

for(int element:a)
	sout(element);
           

打印数组a中的每一个元素,一个元素占一行。当然,传统的for循环也可以实现。但是,for each循环语句显得更加简洁、不易出错。

4. 中断控制流程

break分为两种,一种带标签,一种不带标签。

我们首先来看一下不带标签的break语句。与用于退出的switch语句的break语句一样,它也可以用于退出循环语句。例如:

while (years<=100){
            balance+=payment;
            double interest=balance*interestRate/100;
            balance+=interest;
            if(balance>=goal){
                break;
            }
            years++;
        }
           

在循环开始时,如果years>100,或者在循环体中balance>=goal,则退出循环语句。

下面,我们来看一下带标签的break语句,用于跳出多重嵌套的循环语句。这里用个示例说明了break的工作状态。需要注意的是,标签必须放在希望跳出的最外层循环之前,并且必须跟紧一个冒号。

public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        int n;
        read_data:
        while (...){
            ...
            for(...){
                System.out.println("enter a number >=0:");
                n = in.nextInt();
                if(n>0){
                    break read_data;
                    ....
                }
            }
        }
    }
           

如果输入有误,通过执行带标签的break跳转到带标签的语句块末尾。对于任何使用break语句 代码都需要检测循环是否正常结束,还是由break跳出。

事实上,可以将标签应用到任何语句中,甚至可以应用于if语句或者块语句中,如下所示:

label:{
              ...
              if(condition)
                  break label;
              ...
            }    
           

另外,需要注意的是,只能跳出语句块,不能跳入语句块。

除break语句之外,还有一个continue语句。与break语句一样,它将中断正常的控制流程。continue语句将控制转移到最内层循环的首部。例如:

Scanner in = new Scanner(System.in);
        while (sum<goal) {
            System.out.println("enter a number: ");
            int i = in.nextInt();
            if (i < 0) {
                continue;
            }
            sum+=n;
        }
           

如果n<0,则continue语句越过了当前循环体的剩余部分,立即跳到循环首部。

如果将continue用于for循环,就可以跳到for循环的“更新”部分。

还有一种带标签的continue语句,将跳到与标签匹配的循环首部。这里,不做演示。