java while语句打印三角形_3.8流程控制(循环语句、while语句、for语句)

3.8.2循环语句

3.8.2.1while语句

       最近这些年买彩票只能去投注站买,早些年,笔者经常是在网上买。在网上买有个功能:追号。就是假如你想一直买同一组号码,直到中大奖为止。你可以设置一个条件,比如中了头奖就不继续买了,如果没有中头奖,下一期继续买同样的号码。对于这样的功能,在程序中可以采用while循环来实现:

29202d73cdfe163cc4efbbcd1d15e684.png

代码如下:

while(n<5000000) {      System.out.println("下一期继续买同一组号码");  }

但是事实上,我们先要买第一期,然后才能判断是否中头奖,循环才能继续:

 4ea05d5d9f806a432e4d8ed1a145a4bd.png

代码如下:

do {    System.out.println("买一组号码");} while (n < 5000000);

下面我们再用一个示例来解决我们儿子最近学奥数的一个数学问题,计算1+2+3+…+100;

int sum = 0;// 最终结果,初始为0int add = 1;// 加数,初始为1while (add <= 100) {    sum = sum + add;    add++;// 加完后,自增1}System.out.println(sum);//最终结果是5050

通过上面实例我们知道,当while的条件为真,则执行循环语句。如果这个条件一直为真的话,程序就会进入一个死循环了。因此在实际程序编写的时候,一定要保证这个条件随着程序的运行,会在某一个时刻变为假,避免程序进入死循环。比如上面这个例子变量add会自增,所以一定大于100。

3.8.2.2for语句

       对于上面这个数学问题,我们可以看出来,它的循环次数是固定的,对于这种循环问题,Java还有一种更加简洁的语句来实现,就是for循环。代码可以写成这样:

int sum = 0;// 最终结果,初始为0for (int add = 1; add <= 100; add++) {    sum += add;}System.out.println(sum);// 最终结果是5050

我们可以看到,代码的第2行,把加数add的初始化、循环条件和add的自增都放到一行了,显得更加简洁。它的通用结构如下:

for(表达式1 ; 表达式2 ; 表达式3)

  • 表达式1:一般用来初始化循环迭代计数器

  • 表达式2:必须是一个结果为boolean的表达式,一般用作循环条件

  • 表达式3:一般用来迭代循环计数器

       其实对于for循环中括号内,是分成3个部分,每个部分之间用分号(;)隔开。Java允许这3个部分放置任何表达式,并且都是可以省略不写的。示意图如下:

 3b09d26c9c0c1b109970d8c265777c2a.png

另外,对于在表达式1中声明的变量,它的作用域是整个for循环的循环体。对于在循环语句中定义的变量,作用域只能在循环体{}内。

       有的时候,在一个for循环中,会有多个计数器,例如前面追号买彩票的例子,可以设置追号10期,但是有的时候你的账户余额不足了,彩票站不会给你垫钱追号的,代码可以写成这样:

for (int balance = 10, count = 1; balance >= 2 && count <= 10; count++, balance -= 2) {    System.out.println("余额还剩" + balance + "元,购买第" + count + "期彩票");}
balance:账户余额;count:追号期数

运行结果:

余额还剩10元,购买第1期彩票余额还剩8元,购买第2期彩票余额还剩6元,购买第3期彩票余额还剩4元,购买第4期彩票余额还剩2元,购买第5期彩票

我们可以看到:

  • 表达式1可以同时定义多个同类型的变量(balance和count)

  • 表达式2循环条件是余额大于等于2(够一张彩票钱)并且追号期数小于等于10(我们设置的期数)

  • 表达式3可以同时对balance和count进行更新

虽然Java的语法规则对for循环的表达式1、表达式2、表达式3的限制非常少,但是笔者不建议编写晦涩难懂的语句,尽量保证代码的可读性。

3.8.2.3break

       在上面这个例子中,代码其实写的就有点晦涩,不易阅读。对于余额不足的情况,其实可以认为是中止循环的一个条件。我们可以用break来中止循环,代码可以改写:

int balance = 10;for (int count = 1; count <= 10; count++) {    System.out.println("余额还剩" + balance + "元,购买第" + count + "期彩票");    balance -= 2;    // 当余额不足2元的时候,中止循环    if (balance < 2) {        break;    }}

在while中同样可以使用break,我们将上面代码改写成while版本:

int balance = 10;int count = 1;while (count <= 10) {    System.out.println("余额还剩" + balance + "元,购买第" + count + "期彩票");    count++;    balance -= 2;    // 当余额不足2元的时候,中止循环    if (balance < 2) {        break;    }}

这2段代码的运行结果都是:

余额还剩10元,购买第1期彩票余额还剩8元,购买第2期彩票余额还剩6元,购买第3期彩票余额还剩4元,购买第4期彩票余额还剩2元,购买第5期彩票

break关键字,只能中止当前循环,当有多个循环嵌套使用的时候,有时候想要直接中止最外层循环,对于这种需求,在C++中是使用goto关键字来实现的。我们在学习关键字的时候,发现Java将goto作为保留字了,但是却没有使用它,而是用了另外一种方法来实现。叫做带标签的break语句。

       首先我们得想一个多层嵌套的例子,正当我冥思苦想的时候,突然发我儿子床头的一张乘法口诀表:

82b3a960e89bed30b26531f12e36828c.png

假如我们用程序打印这张表,可以用到2层嵌套的循环语句。第一层循环打印每一行的所有算式,然后我们把打印每一行的功能也用一个循环来实现即第二层循环。代码如下:

// row是行号,一共需要打印9行for (int row = 1; row <= 9; row++) {    // column是列号,对于第row行,一共需要打印row列    for (int column = 1; column <= row; column++) {        System.out.print(column + "×" + row + "=" + column * row + " ");    }    System.out.println();// 打印完一行,需要换行}

运行结果如下:

1×1=11×2=2 2×2=41×3=3 2×3=6 3×3=91×4=4 2×4=8 3×4=12 4×4=161×5=5 2×5=10 3×5=15 4×5=20 5×5=251×6=6 2×6=12 3×6=18 4×6=24 5×6=30 6×6=361×7=7 2×7=14 3×7=21 4×7=28 5×7=35 6×7=42 7×7=491×8=8 2×8=16 3×8=24 4×8=32 5×8=40 6×8=48 7×8=56 8×8=641×9=9 2×9=18 3×9=27 4×9=36 5×9=45 6×9=54 7×9=63 8×9=72 9×9=81

Perfect!完美的打印出来了。假如我们想在打印到第8行第5列的时候,不想打印了,代码改成下面这样:

// row是行号,一共需要打印9行for (int row = 1; row <= 9; row++) {    // column是列号,对于第row行,一共需要打印row列    for (int column = 1; column <= row; column++) {        System.out.print(column + "×" + row + "=" + column * row + " ");        if (row == 8 && column == 5) {            break;        }    }  System.out.println();// 打印完一行,需要换行}

但是这样的结果如下:

1×1=11×2=2 2×2=41×3=3 2×3=6 3×3=91×4=4 2×4=8 3×4=12 4×4=161×5=5 2×5=10 3×5=15 4×5=20 5×5=251×6=6 2×6=12 3×6=18 4×6=24 5×6=30 6×6=361×7=7 2×7=14 3×7=21 4×7=28 5×7=35 6×7=42 7×7=491×8=8 2×8=16 3×8=24 4×8=32 5×8=401×9=9 2×9=18 3×9=27 4×9=36 5×9=45 6×9=54 7×9=63 8×9=72 9×9=81

虽然第8行第5列之后的没有打印,但是第9行又打印出来了。我们再改成带标签的break。

print_row: // 这是一个标签  for (int row = 1; row <= 9; row++) {      // column是列号,对于第row行,一共需要打印row列      for (int column = 1; column <= row; column++) {          System.out.print(column + "×" + row + "=" + column * row + " ");          if (row == 8 && column == 5) {              break print_row;// 中止标签print_row          }      }     System.out.println();// 打印完一行,需要换行 }

运行结果:

1×1=11×2=2 2×2=41×3=3 2×3=6 3×3=91×4=4 2×4=8 3×4=12 4×4=161×5=5 2×5=10 3×5=15 4×5=20 5×5=251×6=6 2×6=12 3×6=18 4×6=24 5×6=30 6×6=361×7=7 2×7=14 3×7=21 4×7=28 5×7=35 6×7=42 7×7=491×8=8 2×8=16 3×8=24 4×8=32 5×8=40

这一次结果正确。我们在第1行添加一个标签“print_row”,然后在第7行中止该标签。这样做相当于跳转到标签“print_row”标记的代码块的末尾即第11行。需要注意的是,标签后面需要紧跟一个冒号(:)。

3.8.2.4continue

       在上面打印乘法口诀表的例子,假如我们不想打印第4行和第4列,想想有啥办法吗?我们可以想到,当打印到第4行的时候,直接换一行去打印第5行。当打印到第4列的时候,也跳过,然后去打印第5列。对于这种需求,我们可以用到continue语句。continue的作用就是跳过当前循环体中剩余的部分,回到当前循环的首部。代码如下:

for (int row = 1; row <= 9; row++) {      /*第4行,打印换行,然后继续打印下一行*/        if (row == 4) {          System.out.println();          continue;      }      for (int column = 1; column <= row; column++) {          /*第4列,打6个空格,然后继续打印下一列*/            if (column == 4) {             System.out.print("      ");             continue;         }         System.out.print(column + "×" + row + "=" + column * row + " ");     }     System.out.println(); }

运行结果如下:

1×1=11×2=2 2×2=41×3=3 2×3=6 3×3=9  1×5=5 2×5=10 3×5=15       5×5=251×6=6 2×6=12 3×6=18       5×6=30 6×6=361×7=7 2×7=14 3×7=21       5×7=35 6×7=42 7×7=491×8=8 2×8=16 3×8=24       5×8=40 6×8=48 7×8=56 8×8=641×9=9 2×9=18 3×9=27       5×9=45 6×9=54 7×9=63 8×9=72 9×9=81

我们看到,结果第4行和第4列都空出来了。需要注意的是,continue只是跳过当前循环体的剩余部分,如果是for循环,表达式3部分还是会执行的。

       continue语句也可以带标签,作用是跳到与标签匹配的循环首部(如果是for循环,则是表达式3)。我们看代码和结果:

print_row:for (int row = 1; row <= 9; row++) {    for (int column = 1; column <= row; column++) {        /*第4列,则直接打印下一行*/          if (column == 4) {            System.out.println();            continue print_row;        }        System.out.print(column + "×" + row + "=" + column * row + " ");    }    System.out.println();}

结果:

1×1=11×2=2 2×2=41×3=3 2×3=6 3×3=91×4=4 2×4=8 3×4=121×5=5 2×5=10 3×5=151×6=6 2×6=12 3×6=181×7=7 2×7=14 3×7=211×8=8 2×8=16 3×8=241×9=9 2×9=18 3×9=27
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值