JAVA基础之五:流程控制

原文地址:http://happyshome.cn/blog/java/basics/flow.html


本文主要介绍了Java中常用的流程控制结构,循环、嵌套循环、条件判断等。 
以及在使用过程中应该注意的问题。

1.  前言

有三种流控制的结构:顺序、条件和循环,如下图所示:

控制结构.png

2. 顺序流控制

程序是一个指令序列。顺序流在程序中使用的是最直接、最常用的,程序语句的执行依赖于写入的顺序。

3.  条件流控制

条件流控制的几种类型:if-then,if-then-else,if-elseif-elseif-...-else,switch-case和条件表达式。

语法 例子 流程图
// if-then
if ( booleanExpression ) {
    true-block ;
}
if (mark >= 50) {
    System.out.println("恭喜!");
    System.out.println("坚持!");
}
流程控制.png
// if-then-else
if ( booleanExpression ) {
    true-block ;
} else {
    false-block ;
}
if (mark >= 50) {
    System.out.println("恭喜!");
    System.out.println("坚持!");
} else {
    System.out.println("努力!");
}
流程控制.png
if ( booleanExpr-1 ) {
    block-1 ;
} else if ( booleanExpr-2 ) {
    block-2 ;
} else if ( booleanExpr-3 ) {
    block-3 ;
} else if ( booleanExpr-4 ) {
    ......
} else {
    elseBlock ;
}
if (mark >= 80) {
    System.out.println("A");
} else if (mark >= 70) {
    System.out.println("B");
} else if (mark >= 60) {
    System.out.println("C");
} else if (mark >= 50) {
    System.out.println("D");
} else {
    System.out.println("F");
}
流程控制.png
// switch-case-default
switch ( selector ) {
    case value-1:
        block-1; break;
    case value-2:
        block-2; break;
    case value-3:
        block-3; break;
    ......
    case value-n:
        block-n; break;
    default:
        default-block;
}
char oper; int num1, num2, result;
......
switch (oper) {
    case '+':
        result = num1 + num2; break;
    case '-':
        result = num1 - num2; break;
    case '*':
        result = num1 * num2; break;
    case '/':
        result = num1 / num2; break;
    default:
        System.err.println("error");
}
Flowchart_SwitchCase.png

括号:当块中只有一条语句,括号是可以省略的,不过建议你保留,括号提高了代码的可读性,举例说明:

if (mark >= 50)
    System.out.println("通过");   // 不推荐这样使用
else {
    System.out.println("失败");
    System.out.println("努力!");
}
switch-case-default

switch-case可以代替nested-if,对于switch-case每种假设必须有break语句,如果缺失break,紧临的假设会被执行,假设条件可以使用int,short或者char(在JDK1.7中可以使用String),不可以使用long,float,double和boolean。

条件运算符(? :)

条件运算符是一个3元运算符。

语法 例子
booleanExpr ? trueExpr : falseExpr
System.out.println((mark >= 50) ? "PASS" : "FAIL");
max = (a > b) ? a : b;   // RHS返回a或者b
abs = (a > 0) ? a : -a;  // RHS返回a或者-a

4. 循环控制流

在Java中有几种类型的循环语句:for, while-do, and do-while。

语法 例子 流程图
// for-loop
for (initialization; test; post-processing){
    body;
}
// 从1加到1000
int sum = 0;
for (int number = 1; number <= 1000; ++number) {
    sum += number;
}
Flowchart_For.png
// while-do loop
while ( test ) {
    body;
}
int sum = 0, number = 1;
while (number <= 1000) {
    sum += number;
    ++number;
}
Flowchart_While.png
// do-while loop
do {
    body;
} while(test);
int sum = 0, number = 1;
do {
    sum += number;
    ++number;
} while (number <= 1000);
Flowchart_DoWhile.png

while-do和do-while的区别在于主体和条件优先执行的次序,在while-do中,优先判断条件,条件为真主体才执行;在do-while中,主体先执行接着判断条件。值得注意的是在do-while中主体至少被执行一次,而对于while-do有可能一次也没有执行。

举例说明:  循环验证用户输入的内容是否为数字,并且在1到10之间。

boolean valid = true;
int number;
do {
    // 你可以提示用户输入1到10
    ......
    valid = number < 1 || number > 10;
} while (valid);

// 使用while-do的例子
boolean valid = true;
while(valid){
    // 你可以提示用户输入1到10
    ......
    valid = number < 1 || number > 10;
} 
空循环体

for ( ; ; ) { body }被称作空循环, 空的初始化语句、测试和后处理,这个空循环体会不断的执行,你可以使用break语句跳出循环。

for-loop和逗号操作符

初始化和后处理你可以使用多条语句,语句之间用逗号分隔,举例:

for (int row = 0, col = 0; row < SIZE; ++row, ++col) {
    ......
}

5. break和continue

break语句用来跳出循环体,continue语句中止当前循环并进行下次循环。

break和continue破坏了代码结构,使代码变的难于理解,所以非必要的时候不推荐使用。

举例说明 (break): 

打印2和上界之间的非素数。

public class NonPrimeList {
    public static void main(String[] args) {
        int upperbound = 100;

        for (int number = 2; number <= upperbound; ++number) {
            // 非素数可以整除2和该数平方根之间的一个数
            int maxFactor = (int)Math.sqrt(number);
            for (int factor = 2; factor <= maxFactor; ++factor) {
                if (number % factor == 0) {
                    System.out.println(number + "是一个非素数");
                    break;   // 找到一个整除的数即可
                }
            }
        }
    }
}

让我们来改写上面的程序,打印出2和上届之间的素数。

public class PrimeListWithBreak {
    public static void main(String[] args) {
        int upperbound = 100;

        for (int number = 2; number <= upperbound; ++number) {
            int maxFactor = (int)Math.sqrt(number);
            boolean isPrime = true;  // 假设当前为素数
            for (int factor = 2; factor <= maxFactor; ++factor) {
                if (number % factor == 0) {
                    isPrime = false;
                    break;
                }
            }

            if (isPrime) System.out.println(number + "是一个素数");
        }
    }
}

让我们来改写上面的程序,不使用break语句,用一个while-loop循环来替代。

public class PrimeList {
    public static void main(String[] args) {
        int upperbound = 100;

        for (int number = 2; number <= upperbound; ++number) {
            int maxFactor = (int)Math.sqrt(number);
            boolean isPrime = true;
            int factor = 2;
            while (isPrime && factor <= maxFactor) {
                if (number % factor == 0) {
                    isPrime = false;
                }
                ++factor;
            }

            if (isPrime) System.out.println(number + "是一个素数");
        }
    }
}
举例说明 (continue):
/*
* 从1累加到上届,11, 22, 33,...
*/
int upperbound = 100;
int sum = 0;

for (int number = 1; number <= upperbound; ++number) {
    if (number % 11 == 0) continue;  // 跳过剩下的语句,继续进行下一次迭代
    sum += number;
}

// 这样写更好
for (int number = 1; number <= upperbound; ++number) {
    if (number % 11 != 0) sum += number;
}
举例说明 (break and continue):
public class MysterySeries {
    public static void main(String[] args) {
        int number = 1;

        while(true) {
            ++number;
            if ((number % 3) == 0) continue;
            if (number == 133) break;
            if ((number % 2) == 0) {
                number += 3;
            } else {
                number -= 3;
            }
            System.out.print(number + " ");
        }
    }
}
标签break.

在嵌套循环中,使用break语句可以跳出内层循环同时继续下一次外层循环,有时候出于某些原因想跳出所有循环,虽然可以使用布尔进行标记,但是未免有些笨拙。这时候我们推荐使用标签break来标记每个循环,例如:

level1:                             // 定义level1循环标签
for (.....) {
    level2:                         // 定义level2循环标签
    for (.....) {
        for (......) {              // level3循环标签
            if (...) break level1;  // 跳出所有循环
            if (...) break level2:  // 跳出level2循环,继续下一次level1循环
                ......
        }
    }
}
标签continue

在嵌套循环中,与标签break类似,你可以使用标签continue来继续指定的循环,例如:

level1:
for (.....) {
    level2:
    for (.....) {
        for (......) {
            if (...) continue level1;  // 马上执行下一次level1循环
            if (...) continue level2:  // 马上执行下一次level2循环
            ......
        }
    }
}

6. 终止程序

System.exit(int exitCode):你可以调用方法System.exit(int exitCode)来终止程序并将控制权返还给Java,按照惯例,exitCode=0表示正常终止,exitCode !=0表示异常终止,例如:

if (errorCount > 10) {
    System.out.println("太多的异常");
    System.exit(1);  // 异常终止
}

同样的,你也可以使用retrun语句直接终止程序。

public static void main(String[] args) {
    ...
    if (errorCount > 10) {
        System.out.println("too many errors");
        return;
    }
    ...
}

7. 嵌套循环

编写程序,使用嵌套循环输出8x8的#,如下:

# # # # # # # #
# # # # # # # #
# # # # # # # #
# # # # # # # #
# # # # # # # #
# # # # # # # #
# # # # # # # #
# # # # # # # #

public class PrintSquarePattern {
    public static void main(String[] args) {
        int size = 8;
        for (int row = 1; row <= size; ++row) {      // 打印行
            for (int col = 1; col <= size; ++col) {  // 打印列
                System.out.print("# ");
            }
            System.out.println();                    // 下一行
        }
    }
}

8. 控制流中的一些问题

摇摆不定的else:想想下面的else匹配哪个if。

if (i == 0)
    if (j == 0)
        System.out.println("i和j都是0");
else
    System.out.println("i不是0");   // 本打算匹配最外层的if

上面的else看上去可以匹配外层if或者内层if,但是Java编译器的匹配规则是就近匹配if,为了使代码的逻辑正确,我们可以使用括号解决,如下所示:

if ( i == 0) {
    if (j == 0) System.out.println("i和j都是0");
} else {
    System.out.println("i不是0");   // 明确的匹配外层if
}

无限循环:请看下面的结构,

while (true) { ...... }

这种写法很常用,通常在循环体内部使用break或者return语句跳出循环,但是这种代码不容易理解,非必要的时候不推荐使用。


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值