
ループ処理(for・while)
この節の目的は、同じ処理をくり返す という考え方を身につけることです。第2章では、2-2 で変数と型、2-3 で条件分岐を学びました。今回はその続きとして、「1回だけではなく、必要な回数だけ動かす」書き方を学びます。Dart 公式では、ループは for、while、do-while、そして break と continue を使って制御すると説明されています。
ループの考え方はかなり古く、回数が決まっている繰り返し を表す代表例として、1957年の FORTRAN Programmer’s Reference Manual には John Backus のチームが設計した DO statement が載っています。そこでは、変数を初期値から増やしながら、ある範囲の文を繰り返し実行すると説明されています。さらに 1970年の Edsger W. Dijkstra の Notes on Structured Programming では、プログラムの基本構造として「連接」「選択」「反復 repetition」が整理され、反復が読みやすいプログラムの中心概念として位置づけられました。つまり、今みなさんが学ぶ for や while は、プログラミングのかなり根っこにある考え方です。
1. ループとは何か
ループとは、同じような処理を何度も実行する仕組みです。たとえば、1から5まで順番に表示する、クラス名簿の全員に対して同じ確認をする、点数一覧を全部表示する、といった場面で使います。もしループがなければ、同じ print() を何回も書かなければならず、とても面倒です。
たとえば、「こんにちは」を3回表示したいだけでも、ループがないとこうなります。
void main() {
print('こんにちは');
print('こんにちは');
print('こんにちは');
}
これでも動きますが、10回、100回になるとつらいです。そこでループを使うと、くり返しのルールだけを書けばよくなります。
2. for ループの基本
for は、何回くり返すかが見えやすいループです。Dart 公式でも、標準的な for loop が最初に紹介されています。
void main() {
for (int i = 1; i <= 5; i++) {
print(i);
}
}
このコードは、1から5まで順に表示します。
for の丸かっこの中には、三つの部分があります。
int i = 1はじめの値を決めます。ここではiを 1 から始めます。i <= 5くり返しを続ける条件です。iが 5 以下なら続けます。i++1回終わるごとにiを 1 増やします。
初心者はここで「いきなり三つもあって難しい」と感じやすいです。けれど、意味はとても素直です。
はじめる → 続ける条件を見る → 1回ごとに変える。
この順番です。
2-1. 学校の例で考える
たとえば、出席番号 1 から 5 の生徒へ順番に声をかけるイメージです。
void main() {
for (int number = 1; number <= 5; number++) {
print('出席番号 $number さん');
}
}
これなら、毎回手で 1、2、3、4、5 と書かなくて済みます。
2-2. 0から始まることに注意
プログラミングでは、List の番号は 0 から始まることがよくあります。
そのため、for でも 0 から始める書き方をよく見ます。
void main() {
List<String> names = ['Aoi', 'Rin', 'Sora'];
for (int i = 0; i < names.length; i++) {
print(names[i]);
}
}
ここでは i が 0、1、2 と動き、names[0]、names[1]、names[2] を順に表示します。i < names.length の < にしているのは、最後の有効な番号が length - 1 だからです。
3. for-in ループ
Dart には、List などの中身を順番に取り出すための for-in ループ があります。公式も、Iterable に対しては for-in が cleaner code だと説明しています。
void main() {
List<String> subjects = ['Math', 'English', 'Science'];
for (var subject in subjects) {
print(subject);
}
}
これは、「subjects の中の要素を、ひとつずつ subject に入れて使う」という意味です。
番号 i を自分で管理しなくてよいので、初心者にはとても読みやすいです。
3-1. どちらを使えばよいか
最初の目安はこうです。
- 番号が必要なら 普通の
for - 中身を順番に見るだけなら
for-in
たとえば、「3人目の名前です」と番号も表示したいなら普通の for が便利です。
ただ名前を順番に読むだけなら for-in のほうがすっきりします。
4. while ループの基本
while は、条件が真である間、くり返す ループです。Dart 公式でも while と do-while が紹介されています。
void main() {
int count = 1;
while (count <= 5) {
print(count);
count++;
}
}
このコードも、1から5まで表示します。
while は for よりも形がシンプルです。
- まず条件を書く
- 条件が true の間だけ中身を実行する その代わり、中で値を変えるのを忘れると終わらない ことがあります。
4-1. while が向いている場面
while は、何回くり返すかが最初からはっきりしないとき に向いています。
たとえば、次のような場面です。
- パスワードが正しくなるまで入力を受け付ける
- 在庫がある間、商品を処理する
- プレイヤーの HP が 0 より大きい間、ゲームを続ける
「5回くり返す」と決まっているなら for が自然です。
「条件が満たされている間だけ続ける」なら while が自然です。
4-2. 無限ループに注意
次のコードは危険です。
void main() {
int count = 1;
while (count <= 5) {
print(count);
}
}
count++ がないので、count はずっと 1 のままです。
すると count <= 5 はずっと true で、終わりません。
これを無限ループといいます。初心者が最初にやりがちなミスの一つです。
5. do-while を軽く知っておく
今回の見出しは for と while ですが、Dart では do-while もあります。
これは、最初の1回は必ず実行してから条件を見る ループです。公式も while and do-while をセットで説明しています。
void main() {
int count = 1;
do {
print(count);
count++;
} while (count <= 3);
}
これは 1、2、3 を表示します。
while との違いは、条件を見るタイミングです。
whileは 先に条件を見るdo-whileは 先に1回実行してから条件を見る 今は「そういう種類もある」と知っていれば十分です。
6. ループの中で if を使う
ループと条件分岐は、よく一緒に使います。
たとえば、1から10までのうち、偶数だけ表示したいとします。
void main() {
for (int i = 1; i <= 10; i++) {
if (i % 2 == 0) {
print(i);
}
}
}
% は余りを求める記号です。
i % 2 == 0 は、「2で割った余りが 0、つまり偶数」という意味です。
こうして見ると、前の 2-3 で学んだ条件分岐が、ループの中でそのまま役立っていることが分かります。
7. break と continue を軽く知っておく
Dart のループでは、break と continue も使えます。公式でも loops の一部として説明されています。
7-1. break
break は、その場でループを終わらせる 命令です。
void main() {
for (int i = 1; i <= 10; i++) {
if (i == 4) {
break;
}
print(i);
}
}
このコードでは、1 2 3 まで表示されて終わります。i == 4 になった時点で break が実行されるからです。
7-2. continue
continue は、その回だけスキップして次へ進む 命令です。
void main() {
for (int i = 1; i <= 5; i++) {
if (i == 3) {
continue;
}
print(i);
}
}
このコードでは、1 2 4 5 が表示されます。3 の回だけ飛ばしているからです。
初心者の最初の目安としては、break と continue は便利ですが、使いすぎると流れが読みにくくなることがあります。まずは普通の for と while をしっかり押さえるのが大切です。
8. 歴史を整理する
ループ処理の考え方は、ただ「便利だから生まれた」のではありません。
1957年の FORTRAN manual にある DO statement は、回数が決まった反復 をかなりはっきりした形で示していました。そこでは、変数の開始値、終了値、増分を与えて、指定範囲の文を繰り返すと説明されています。これは今の for にかなり近い考え方です。
その後、Edsger W. Dijkstra は 1970年の Notes on Structured Programming で、プログラムを考える基本構造として「連接」「選択」「反復」を整理しました。ここで重要なのは、反復がただの省力化ではなく、読みやすく、正しさを考えやすいプログラムの柱 として扱われたことです。いま私たちが for と while を自然に使えるのは、こうした structured programming の考え方が広まったからでもあります。
9. 実践
実践1:1から5まで表示する
void main() {
for (int i = 1; i <= 5; i++) {
print(i);
}
}
実践2:List の中身を全部表示する
void main() {
List<String> members = ['Aoi', 'Rin', 'Sora'];
for (var member in members) {
print(member);
}
}
実践3:while でカウントする
void main() {
int count = 3;
while (count > 0) {
print('残り $count 回');
count--;
}
print('終了');
}
実践4:偶数だけ表示する
void main() {
for (int i = 1; i <= 10; i++) {
if (i % 2 == 0) {
print(i);
}
}
}
ここまで読めたら、
「ループは、同じ処理を必要なだけ実行する仕組み」
「for は回数が見えやすい」
「while は条件が中心」
という感覚がつかめているはずです。
10. 練習問題
問題1
次のコードは何を表示しますか。
void main() {
for (int i = 1; i <= 3; i++) {
print('こんにちは');
}
}
問題2
次のコードは何を表示しますか。
void main() {
int count = 2;
while (count <= 4) {
print(count);
count++;
}
}
問題3
次のコードの問題点を説明してください。
void main() {
int x = 1;
while (x < 5) {
print(x);
}
}
問題4
次の List の中身を for-in で全部表示するコードを書いてみてください。
List<String> fruits = ['apple', 'banana', 'orange'];
問題5
次のコードは何を表示しますか。
void main() {
for (int i = 1; i <= 5; i++) {
if (i == 3) {
continue;
}
print(i);
}
}
問題6
for と while の違いを、初心者向けに一文ずつ説明してみてください。
11. 練習問題の答え
答え1
こんにちは を 3 回表示します。i が 1、2、3 のときにくり返すからです。
答え2
2、3、4 を順に表示します。count は 2 から始まり、毎回 1 増えて、4 まで表示されます。
答え3
x の値が変わらないので、条件 x < 5 がずっと true のままになります。
そのため、無限ループになります。
答え4
例です。
void main() {
List<String> fruits = ['apple', 'banana', 'orange'];
for (var fruit in fruits) {
print(fruit);
}
}
答え5
1、2、4、5 を表示します。i == 3 の回だけ continue でスキップするからです。Dart の loops では continue を使って現在の反復を飛ばし、次へ進めます。
答え6
例です。
forは、何回くり返すかが見えやすいときに使うループです。whileは、条件が true の間だけ続けたいときに使うループです。
12. まとめ
この節では、ループ処理の基本を学びました。
for は、開始・条件・変化をまとめて書けるので、回数の見通しが立ちやすいループです。
for-in は、List などの中身を順番に見るのに向いています。
while は、条件が true の間だけ続けたいときに使います。
do-while は最初の 1 回を必ず実行する形です。
そして break は途中で終了、continue はその回だけ飛ばす命令でした。Dart 公式も、これらを loops の基本として整理しています。
歴史的に見ると、1957年の FORTRAN の DO statement は、回数の決まった反復を表す代表的な初期例でした。その後、Dijkstra が 1970年に structured programming の中で「反復」を基本構造として強調し、読みやすく正しさを考えやすいプログラムの中心に置きました。だから、いま学んでいるループは単なる便利機能ではなく、プログラムを整理して書くための核なのです。
次節では、処理に名前をつけてまとめる 関数 を学びます。ループで同じ流れをくり返せるようになった次は、その処理自体をひとまとまりにする段階へ進みます。