for 与 while 循环

控制结构里的循环指的是重复执行一段代码,直到循环条件不再满足,或使用break关键字跳出循环。Dart控制结构里的循环包括:

  • 经典 for 循环
  • for-in 循环
  • while 循环
  • do-while循环

for 循环

下面这段代码使用经典的for循环打印数字0到9。

// ch0202_1.dart
void main() {
  for (var i = 0; i < 10; i++) {
    print('$i');
  }
}

经典for循环的语法:

  for (初始化列表; 循环条件; 后置操作) {
    循环体
  }
flowchart TD
    A([初始化列表]) --> B{循环条件}
    B -->|true| C(循环体)
    C -->|continue| D(后置操作)
    D --> B
    B ---->|false| E([End])
    C ---->|break| E

后置操作即执行完循环体之后的操作。初始化列表、 循环条件、后置操作,这三部分用分号(;)分割,且每一部分都可以省略(但必须保留分号)。如果循环体只有一条语句,包围循环体的那对花括号({}) 可以省略,但不建议这么做。

下面这段代码将打印九九乘法表:

// ch0202_2.dart
import 'dart:io';

import 'package:sprintf/sprintf.dart';

void main() {
  for (var i = 1; i < 10; i++) {
    for (var j = 1; j < 10; j++) {
      stdout.write(sprintf('%2d ', [i * j]));
    }
    stdout.write('\n');
  }
}

下面这段代码将数字10分解为2个非负整数之和:

// ch0202_3.dart
void main() {
  for (var i = 0, j = 10; i <= j; i++, j--) {
    print('$i + $j = 10');
  }
  // Output:
  // 0 + 10 = 10
  // 1 + 9 = 10
  // 2 + 8 = 10
  // 3 + 7 = 10
  // 4 + 6 = 10
  // 5 + 5 = 10
}

下面这段代码的功能一样,但省略了循环条件 i <= j, 改用break语句来跳出循环:

// ch0202_4.dart
void main() {
  for (var i = 0, j = 10; ; i++, j--) {
    if (i > j) break;
    print('$i + $j = 10');
  }
}

for-in

使用经典的for语句打印字母A-E:

// ch0202_5.dart
import 'dart:io';

void main() {
  var letters = ['A', 'B', 'C', 'D', 'E'];
  for (var i = 0; i < letters.length; i++) {
    stdout.write('${letters[i]} '); // Output: A B C D E
  }
}

使用 for-in语句改写上述代码,更为简洁:

// ch0202_6.dart
import 'dart:io';

void main() {
  var letters = ['A', 'B', 'C', 'D', 'E'];
  for (var letter in letters) {
    stdout.write('$letter '); // Output: A B C D E
  }
}

whiledo-while

while 循环在循环体之前检查循环条件,而do-while则是在循环提之后检查。

while 循环:

flowchart TD
    B{循环条件}-->|true| C(循环体)
    C -->|continue| B
    C -->|break|E
    B ---->|false| E([End])

do-while 循环:

flowchart TD
    C(循环体) -->|continue| B{循环条件}
    B -->|true| C
    C -->|break|E
    B ---->|false| E([End])

下面这段代码先打印数字0到9,再打印数字10到1(递减)。

//ch0102_7.dart
void main() {
  // print 0,1,...,9
  var x = 0;
  while (x < 10) {
    print(x++);
  }

  // print 10,9,...,1
  do {
    print(x--);
  } while (x > 0);
}

breakcontinue

break用于跳出当前循环,continue用于跳转至下一次迭代。下面这段代码使用for循环,打印1到9之间的奇数。

// ch0202_8.dart
void main() {
  for (var x = 1; ; x++) {
    if (x == 10) break;
    if (x % 2 == 0) continue;
    print(x);
  }
}

标签

breakcontinue 仅对所在的(内层)循环起作用。如果要跳出(break)外层循环,或跳转至(continue)外层循环的下一次迭代,须借助标签。标签是一个标识符,后跟冒号(labelName:);将标签放在语句之前以创建带标签的语句。

// ch0202_9.dart

import 'dart:io';

void main() {
  outerLoop:
  for (var i = 0; i < 10; i++, print('')) {
    for (var j = 0; j < 10; j++) {
      if (j == 4) continue outerLoop;
      stdout.write(' ' * (i > 0 ? 1 : 2));
      stdout.write(10 * i + j);
    }
  }
}

此例中的 continue outerLoop; 就相当于 break

练习

  • 分别使用 whiledo-while 改写 ch0202_8.dart
  • 示例 ch0202_9.dart 中,如果将 continue outerLoop; 改为 break outerLoop; 程序的输出是什么?