JAVA基础05循环

本文详细介绍了Java中的循环结构,包括while、do-while和for循环的使用,强调了循环设计策略、循环控制以及如何避免无限循环和差一错误。此外,还探讨了输入输出重定向、循环中使用标记值控制以及break和continue的关键作用,帮助开发者更好地理解和应用Java循环。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

5. 循环

循环是用来控制语句块重复执行的一种结构循环的概念是程序设计的基础Java 提供了三种类型的循环语句:while 循环do - while 循环和 for 循环

5.1  while 循环

while 循环在条件为真的情况下重复地执行语句

while 循环的语法如下 :
while( 循环继续条件){ 
// 循环体
    语句 (组);
 }

下图给出了 while 循环的流程图循环中包含的重复执行的语句部分称为循环体(loop body)循环体的每一次执行都被认为是一次循环的迭代或重复)每个循环都含有循环继续条件,循环继续条件是一个布尔表达式控制循环体的执行在循环体执行前总是先计算循环条件以决定是否执行它。若条件为 true, 则执行循环体若条件为 false则终止整个循环,并且程序控制转移到 while 循环后的下一条语句

确切地知道循环体需要执行的次数所以使用一个控制变量 count 来对执行次数计数。这种类型的循环称为计数器控制的循环counter - controlled loop)

注意:循环继续条件应该总是放在括号内。只有当循环体只包含一条语句或不包含语句时,循环体的花括号才可以省略

注意要保证循环继续条件最终可以变为 false以便程序能够结束一个常见的程序设计错误是无限循环(也就是说循环会永远执行下去如果程序运行了不寻常的长时间而不结束,可能其中有无限循环如果你是从命令窗口运行程序的CTRL+C 键来结束

警告程序员经常会犯的错误就是使循环多执行一次或少执行一次这种情况通常称为差一错误( off - by - one error)例如下面的循环会将 Welcome to ]ava 显示 101 而不是100 次这个错误出在条件部分所以条件应该是 count<100 而不是 count<=100

int count = 0;
while (count <= 100){
    System.out.println("Weicome to Java!");
    count++; 
}

 

5.1.1 循环设计策略

编写一个正确的循环对编程新手来说并不是件容易的事编写循环时应该考虑如下三个步骤:

第一步确定需要重复的语句

第二步将这些语句放在一个循环中如下所示

while(true){
    语句组 ; 
}

第三步为循环继续条件编码并为控制循环添加适合的语句

while( 循环继续条件){
    语句组 ;
    用于控制循环的附件语句 ; 
} 

 

5.1.2 使用标记值控制循环

另一种控制循环的常用技术是在读取和处理一个集合的值时指派一个特殊值这个特殊的输人值也称为标记值(sentinel value), 用以表明循环的结束如果一个循环使用标记值来控制它的执行,它就称为标记位控制的循环sentinel - controlled loop)

注意:在循环控制中,不要使用浮点值来比较值是否相等因为浮点值都是某些值的近似值,使用它们可能导致不精确的循环次数和不准确的结果

考虑下面计算 1+0.9+0.8+ . . .+0.1的代码

double item = 1; double sum = 0;
while (item != 0) { // No guarantee item will be 0
    sum += item;
    item -= 0.1; 
}
System.out.println(sum);

变量 item 1开始每执行一次循环体就减去 0.1item 变为 0 时循环应该终止但是,因为浮点數在算术上是近似的所以不能确保 item 会变成真正的 0从表面上看,这个循环似乎没问題,但实际上它是一个无限循环

 

5.1.3 输入和输出重定向

在前面的例子中如果要输人大量的数值那么从键盘上输入是非常繁琐的事可以将这些数据用空格隔开,保存在一个名为 input.txt 的文本文件中然后使用下面的命令运行这个程序:

java SentinelValue < input.txt

这个命令称为输入重定向input redirection)程序从文件 input.txt 中读取输入而不是让用户在运行时从键盘输入数据。假设文件内容是

2 3 4 5 6 7 8 9 12 23 32
23 45 67 89 92 12 34 35 3 1 2 4 0

程序将得到 sum 值为 518

类似地还有输出重定向output redirection), 输出重定向将输出发送给文件而不是将它们显示在控制台上。输出重定向的命令为

java ClassName > output.txt

可以在同一命令中同时使用输入重定向和输出重定向例如下面的命令从文件 input txt 中获取输入并将输出发送给文件 output.txt:

java SentinelValue <input.txt> output.txt

 

 

5.2 do - while 循环

do - while 循环和 while 循环基本一样不同的是它先执行循环体一次然后判断循环继续条件

do - while 循环是 while 循环的变体它的语法如下

do {
// 循环体 ;
    语句(组 ); 
} while ( 循环继续条件);

执行流程图如下所示首先执行循环体,然后计算循环继续条件如果计算结果为 true, 则重复执行循环体如果为 false, 则终止 do - while 循环while 循环与 do - while 循环的差别在于:计算循环继续条件和执行循环体的先后顺序不同。有时候选择其中一种会比另一种更方便

提示如果循环中的语句至少需要执行一次建议使用 do-while 循环前面程序TestDoWhile 中 do-while 循环的情形就是如此如果使用 while 循环那么这些语句必须在循环前和循环内都出现。

 

 

5.3 for 循环

for 循环具有编写循环的简明语法

经常会用到下面的通用形式编写循环

i = initialValue; // Initialize loop control variable
while (i < endValue) 
// Loop body
    ...
    i++; // Adjust loop control variable
}

可以使用 for 循环简化前面的循环

for (i = initialValue; i < endValue; i++) {
// Loop body
    ...
}

通常for 循环的语法如下所示

for (初始操作;循环鏈续条件;每次迭代后的操作){ 
// 循环体;
    语句(组); 
}

for 循环的流程图如图所示

 

for 循环语句从关键字 for 开始然后是用双括号括住的循环控制结构体这个结构体包括初始动作、循环继续条件和每次迭代后的动作控制结构体后紧跟着花括号括起来的循环体。初始动作循环继续条件和每次迭代后的动作都要用分号分隔。一般情况下,for 循环使用一个变量来控制循环体的执行次数以及什么时候循环终止。这个变量称为控制变量(control variable)初始化动作是指初始化控制变量每次迭代后的动作通常会对控制变量做自增或自减,而循环继续条件检验控制变量是否达到终止值例如,下面的 for 循环打印 Welcome to Java! 100

int i;
for(i = 0;i < 100;i++){
    System.out.println("Weicowe to Java!"); 
}

循环控制变量可以在 for 循环中声明和初始化下面就是一个例子

for(int = 0;i<100;i++){
    System.out.println("Weicome to Java!");
}

如果像这个例子一样循环体内只有一条语句则可以省略花括号

提示控制变量必须在循环控制结构体内或循环前说明如果循环控制变量只在循环内使用而不在其他地方使用,那么在 for 循环的初始动作中声明它是一个很好的编程习慣如果在循环控制结构体内声明变量,那么在循环外不能引用它例如不能在前面代码的for 循环外引用变量 i, 因为它是在 for 循环内声明的

注意for 循环中的初始动作可以是 0 个或是多个以逗号隔开的变量声明语句或赋值表达式例如

for(int i=0,j=0;i+j<10;i++, j++){ 
// Do something
}

for 循环中每次迭代后的动作可以是 0 个或多个以逗号隔开的语句例如

for(int i=1;i<100; System.out.println(i), i++);

这个例子是正确的但是它不是一个好例子因为它增加了程序的阅读难度通常将声明和初始化一个变量作为初始动作,将增加或减少控制变量作为每次迭代后的操作

注意如果省略 for 循环中的循环继续条件,则隐含地认为循环继续条件为 true因此,下面图 a 中给出的语句和图 b 中给出的语句一样它们都是无限循环但是为了避免混淆,最好还是使用图 c 中的等价循环

 

 

 

5.4 采用哪种循环

可以根据哪个更加方便来使用 for 循环while 循环或者 do - while 循环while 循环和 for 循环都称为前测循环pretestoop), 因为继续条件是在循环体执行之前检测的,do - while 循环称为后测循环posttest loop), 因为循环条件是在循环体执行之后检测的。三种形式的循环语句whiledo - while 和 for, 在表达上是等价的也就是说,可以使用这三种形式之一来编写一个循环。例如下面图 a while 循环总能转化为图 b中的 for 循环

除了某些特殊情况外下面图 a 中的 for 循环通常都能转化为图 b 中的 while 循环

建议使用自己觉得最自然最舒服的一种循环语句通常如果已经提前知道重复次数,那就采用 for 循环例如需要打印一条信息 100 次时如果无法确定重复次数就采用 while 循环就像读入一些数值直到读入 0 为止的这种情况如果在检验继续条件前需要执行循环体,就用 do - while 循环替代 while 循环

for 子句的末尾和循环体之间多写分号是一个常见的错误,如下面的图 a 中所示。图 a 中分号过早地表明循环的结束循环体实际上都是为空的如图 b 所示a 和图 b 是等价的,都是不正确的类似地c 中的循环也是错的c 与图 d 等价都是不正确的

通常在使用次行块格式时容易发生这些错误使用行尾块风格可以避免这种类型的错误。在 do-while 循环中需要分号来结束这个循环

 

 

5.5 嵌套循环

一个循环可以嵌套在另外一个循环中。嵌套循环是由一个外层循环和一个或多个内层循环组成的。每当重复执行一次外层循环时将再次进人内部循环,然后重新开始

注意需要注意的是嵌套循环将运行较长时间考虑下面嵌套三层的循环

for (int i = 0;i < 10000;i++){
    for (int j = 0;j < 10000;j++){
        for (int k = 0; k < 10000; k++){
            Perform an action;
        }
    }
}

动作将被执行万亿次如果需要丨微秒来执行一次动作整个循环花费的事件将大于 2 7 7 小时。注意1 微秒等于 1 秒的百万分之一

 

 

5.6 最小化数值错误

在循环继续条件中使用浮点数将导致数值错误

涉及浮点数的数值误差是不可避免的因为浮点数在计算机中本身就是近似表示的本节将通过实例讨论如何最小化这种误差。 用下列给出的例子计算从 0.011.0 的数列之和该数列中的数值以 0.01递增,如下所示0.01+0.02+0.03 + ...。

    TestSum.java
public class TestSum { 
    public static void main (String[] args) { 
    // Initialize sum
        float sum = 0; 

        // Add 0.01,0.02, … ,0.99, 1 to sum
        for (float i - 0.0lf ; i <= l.0f ; i = i + 0.01f) {
            sum +- i ; 
        }
        // Display result
        System.out. println("The sum is " + sum);
    }
}

显示

The sum is 50.499985

for 循环7 ~8 重复地将控制变量 i 加到 sum 变量 i 0.01 开始每次迭代增加 0.01i 超过 1.0 时循环终止

for 循环初始动作可以是任何语句但是它经常用来初始化控制变量从本例中可以看到,控制变量可以是 float 事实上它可以为任意数据类型。sum 的精确结果应该是 SO.50, 但是答案是 S0.49998S这个结果是不精确的因为计算机使用固定位数表示浮点数,因此它就不能精确表示某些浮点数如果如下所示将程序中的 float 型改成 double 应该可以看到精度有一些小小的改善因为 double 型变量占64 位而 float 型变量只占 32

 

 

5.7 关键字 break continue

关键字 break continue 都可以在循环语句中使用为循环提供额外的控制。在某些情况下,使用 break continue 可以简化程序设计但是过度使用或者不正确地使用它们会使得程序难以读懂也难以调试。

你已经在 switch 语句中使用过关键字 break你也可以在一个循环中使用 break 立即终止该循环。下列程序清单给出的程序演示了在循环中使用 break 的效果

    TestBreak.java
public class TestBreak {
    public static void main(String[] args){
        int sum = 0;
        int number = 0;
        while(number < 20){
            number++;
            sum += number;
                if(sum >= 100){
                    break;
                }
            }
        System.out.println("The number is" + number);
        System.out.println("The sum is" + sum);
    }
}

显示

The number is 14;
The sum is 105;

上述程序清单中的程序将从120 的整数依次加到 sum 直到 sum 大于或等于 100。如果没有 if 语句9)该程序计算从120 之间整数的和但是有了 if语句那么当总和大于或等于 100 这个循环就会终止没有 if 语句程序输出结果将会是

The number is 20;
The sum is 210;

也可以在循环中使用关键字 continue当程序遇到 continue 它会结束当前的迭代。程序控制转向该循环体的末尾。换句话说continue 只是跳出了一次迭代而关键字 break是跳出了整个循环。下列程序清单给出的程序演示了在循环中使用 continue 的效果

    TestContinue.java
public class TestContinue { 
    public static void main(tring[] args){ 
        int sum = 0; 
        int number = 0; 

        while(number < 20){ 
            number++; 
            if(number ==10 || number == 11){
                continue;
            }
            sum += number;
        }
        System.out.println("The sum is" + sum);
    }
}

显示

The sum is 189

上述程序清单中的程序120 中除去10 11外的整数都加到 sum 程序中有了 if 语句8 )number 10 11时就会执行 continue 语句continue 语句结束了当前迭代,就不再执行循环体中的其他语句因此number 10 11,它就没有被加到 sum 若程序中没有 if 语句程序的输出就会如下所示

The sum is 210

在这种情况下,即使当 number 10 11也要将所有的数都加到 sum 因此,结果为 210, 这个值比有 if 语句的情况获取的值大了 21

注意continue 语句总是在一个循环内while do - while 循环中continue 语句之后会马上计算循环继续条件;而在 for 循环中continue 语句之后会立即先执行每次迭代后的动作,再计算循环继续条件

总是可以编写在循环中不使用 break contimje 的程序通常只有在能够简化代码并使程序更容易阅读的情况下,才适合使用 break continue。假设你需要编写一个程序,找到整数 n 的除1外的最小因子假设 n>=2)可以使用 break 语句编写简单直观的代码如下所示

int factor = 2;
while (factor <= n){ 
    if (n % factor == 0){
        break;
        }
    factor++; 
    }
System.out.println("The smallest factor other than 1 for " + n + " is " + factor);

你也可以不使用 break 语句重写该代码如下所示

boolean found = false;
int factor = 2;
while (factor <= n && !found){
    if (n % factor = 0){
        found = true;
    }else{
        factor++; 
    }
}
System.out.println("The smallest factor other than 1 for " + n + " is "+ factor);

显然使用 break 语句可以使程序更简单和更易读但是应该谨慎使用 break 和 continue。过多使用 break continue 会使循环有很多退出点使程序很难阅读

注意很多程序设计语言都有 goto 语句goto 语句可以随意地将控制转移到程序中的任意一条语句上,然后执行它这使程序很容易出错Java 中的 break 语句和 continue 语句是不同于 goto 语句的它们只能运行在循环中或者 switch 语句中break 语句跳出整个循环,continue 语句跳出循环的当前迭代

注意编程是一个富于创造性的工作有许多不同的方式来编写代码事实上,你可以通过更加闻单的代码来找到最小因子,如下所示:

int factor = 2;
while (factor <= n && n % factor != 0){
    factor++;
}

 

 

 

编译运算练习

1.

 

 

2.

 

 

3.

 

 

4.

 

 

5.

 

 

6.

 

 

7.

 

 

8.

 

9.

 

 

10.

 

11.

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值