何度も何度もやってみる。そして少数の都合のよい可能な場合を見逃さないように、試行を変えることである。(中略)また試行の失敗からより多くのことを学ぶ事ができるのだ。
『数学の問題の発見的解き方』George Polya著、柴垣和三雄、金山靖夫訳より引用
ループとはなんだろうか。ためしに辞書で引いてみると、そのものずばりの説明がある:
具体的なコードを見ていこう:
var i: Integer; begin for i := 0 to 2 do begin Writeln('Gold'); end; Readln; end.
Gold Gold Gold
このコードから、まず読み取ってほしいことは、
Writeln('Gold');
が 3 回実行されるということだ。なぜ(4 回ではなく) 3 回なのだろうか。
次のコード:
for i := 0 to 2 do begin Writeln('Gold'); end;
このコードは Writeln('Gold'); を 3 回実行した。もし、これを 5 回実行したいとすると、どこを修正したらよいか分かるだろうか?2 通りの修正の仕方がある。これからそのコードを示すが、いったんここで本文を読むのを止めて、ぜひあなた自身で見つけてほしい。
1 つは次のようになる:
var i: Integer; begin for i := 0 to 4 do begin Writeln('Gold'); end; Readln; end.
もう 1 つは次のように:
var i: Integer; begin for i := -2 to 2 do begin Writeln('Gold'); end; Readln; end.
for 文は次のようにみる:
for <カウンタ> := <初期値> to <終値> do begin <文> end;
ループする回数は、「<終値> - <初期値> + 1」となる。<カウンタ> には「<初期値> + それまでにループした回数」が格納される。<カウンタ> の値を表示させるプログラムを書いてそれを確かめよう。
var i: Integer; begin for i := 0 to 5 do begin Writeln(i); end; Writeln('---'); for i := 4 to 6 do begin Writeln(i); end; Readln; end;
0 1 2 3 4 5 --- 4 5 6
あなたへの課題:
for 文も if 文同様、実行する文が一つだけの場合に限って、begin
と end
を省略できる:
var i: Integer; begin for i := 0 to 2 do Writeln('foo'); Readln; end.
foo foo foo
配列の要素を全て表示するには for 文を使うと簡単になる。for 文を使わないと次のようなコードになるが、
var Ary: array[0..3] of Integer; begin Ary[0] := 0; Ary[1] := 10; Ary[2] := 20; Ary[3] := 30; Writeln(Ary[0]); Writeln(Ary[1]); Writeln(Ary[2]); Writeln(Ary[3]); Readln; end.
0 10 20 30
for 文を使うと、こうなる:
var Ary: array[0..3] of Integer; i: Integer; begin for i := 0 to 3 do Ary[i] := 10 * i; for i := 0 to 3 do Writeln(Ary[i]); Readln; end.
0 10 20 30
Low 関数と High 関数を使えば、配列の下限値と上限値が得られるので、for 文を次のように書き直すと、まちがいを起こしにくくなる。
var Ary: array[0..3] of Integer; i: Integer; begin for i := Low(Ary) to High(Ary) do Ary[i] := 10 * i; for i := Low(Ary) to High(Ary) do Writeln(Ary[i]); Readln; end.
0 10 20 30
たとえば、1 から 100 までの整数の合計を計算するコードは for 文で次のように書ける。
var i, Sum: Integer; begin Sum := 0; for i := 1 to 100 do Sum := Sum + i; Writeln(Sum); Readln; end.
5050
1 から 10 までの整数の中で偶数を表示させるコードも for 文を使えば簡単に書ける。
var i: Integer; begin for i := 1 to 10 do if (i mod 2) = 0 then Writeln(i); Readln; end.
2 4 6 8 10
あなたへの課題:1 から 10 までの偶数の合計を表示するプログラムを書いてください
for 文を入れ子にして利用すると、九九の表が作れる。
var i, j: Integer; begin for i := 1 to 9 do begin for j := 1 to 9 do Write(Format('%2d ', [i * j])); Writeln; end; Readln; end.
1 2 3 4 5 6 7 8 9 2 4 6 8 10 12 14 16 18 3 6 9 12 15 18 21 24 27 4 8 12 16 20 24 28 32 36 5 10 15 20 25 30 35 40 45 6 12 18 24 30 36 42 48 54 7 14 21 28 35 42 49 56 63 8 16 24 32 40 48 56 64 72 9 18 27 36 45 54 63 72 81
Format は文字列を返す関数である。使用例については、次のサンプルを参考にしてほしい。
という点に注目してコードをみよう。
begin Writeln('>>' + Format('%d', [27]) + '<<'); Writeln('>>' + Format('%10d', [27]) + '<<'); Writeln('>>' + Format('%-10d', [27]) + '<<'); Readln; end.
>>27<< >> 27<< >>27 <<
また、次のような三角形を表示させるプログラムも for 文を使えばできる。
o oo ooo oooo
var i, j: Integer; begin for i := 1 to 4 do begin for j := 1 to i do Write('o'); Writeln; end; Readln; end.
あなたへの課題:次の三角形を表示させるプログラムを for 文を使って書いてください
o oo ooo oooo ooo oo o
あなたへの課題:次の三角形を表示させるプログラムを for 文を使って書いてください
o ooo ooooo ooooooo
あなたへの課題:次の三角形を表示させるプログラムを for 文を使って書いてください
o o o o o ooooooo
ループには for 文のほかに while 文がある。while 文を使って、1 から 9 までの合計を表示するプログラムは次のように書ける。
var x, Sum: Integer; begin x := 1; Sum := 0; while x < 10 do begin Sum := Sum + x; x := x + 1; end; Writeln(Sum); Readln; end.
45
while のコードを図示すると次のようになる:
while x < 10 do begin Sum := Sum + x; x := x + 1; end;
while <条件> do begin <文> end;
<条件> が False を返すとき、ループが終了する。<条件> が True を返すなら <文> が実行され、再び <条件> の判定に戻り、同じ事を繰り返す。
while 文と似たループに repeat 文がある。repeat 文と while 文との違いは一つしかない。それは、ループするかどうかの判定を最初に行うかそれとも最後に行うかだ。
先ほどの while 文のコードを repeat 文に書き直してみよう。
var x, Sum: Integer; begin x := 1; Sum := 0; repeat Sum := Sum + x; x := x + 1; until x = 10; Writeln(Sum); Readln; end.
45
repeat 文を図にすると次のようになる:
repeat Sum := Sum + x; x := x + 1; until x = 10;
while 文のところで示した図とどこが違うだろうか。ひし形の図形の位置する場所が変わったのが分かる。
repeat <文> until <条件>
repeat 文では <文> をまず実行する。そして <条件> が True を返すとき、ループは終了する。<条件> が False を返すなら、再び <コード> が実行される。以降同じことを繰り返す。while 文では <条件> が False ならループは終了した。 repeat 文では <条件> が True であればループが終了する。
考えを広げるために:
repeat 文:
repeat <文> until <条件>
とあるとき、<文> がいくつあろうと begin
, end
は必要としない。つまり、
repeat begin <文> end until <条件>
のようには書かない。なぜだろうか。
逆に考えてみよう。if 文や while, for 文では、なぜ begin と end が必要なのだろうか。なぜ while 文などでは、<条件>が True のとき実行される文がたったの一つであれば、begin と end が省略できるのか。
あなたへの課題:次のプログラムは数当てゲームです。このプログラムをエディタに打ち込んで、遊んでみてください。
var x, Ans: Integer; s: string; begin Randomize; Ans := Random(100)+1; repeat Write('数値を入力して下さい(0で終了):'); Readln(s); x := StrToIntDef(s, 0); if x = Ans then begin Writeln('正解'); break; end else if x > Ans then Writeln('もう少し下です') else Writeln('もう少し上です'); until x = 0; Writeln('エンターキーで終了します'); Readln; end.
数値を入力して下さい(0で終了):35 もう少し下です 数値を入力して下さい(0で終了):22 もう少し下です 数値を入力して下さい(0で終了):13 正解 エンターキーで終了します
一回だけループする for 文:
var i: Integer; begin for i := 0 to 0 do begin Writeln('Gold'); end; Readln; end.
一回もループしない for 文:
var i: Integer; begin for i := 0 to -1 do begin Writeln('Gold'); end; Readln; end.
※上のコードを実行しようとすると、
[ヒント] 一度も実行されない for/while ループがあります - 削除しました
とヒントが表示されるだろう。
1 から 10 までの偶数の合計を表示するプログラム:
var i, Sum: Integer; begin Sum := 0; for i := 1 to 10 do if (i mod 2) = 0 then Sum := Sum + i; Writeln(Sum); Readln; end.
次の三角形を表示させるプログラム:
o oo ooo oooo ooo oo o
var i, j, n, Top: Integer; begin Top := 4; // 三角形の頂上までの "o" の個数 for i := 1 to Top * 2 - 1 do begin if i > Top then n := Top * 2 - i else n := i; for j := 1 to n do Write('o'); Writeln; end; Readln; end.
次の三角形を表示させるプログラム:
o ooo ooooo ooooooo
var i, j, Top, Len: Integer; begin Len := 1; Top := 4; // 三角形の底辺から頂上までの "o" の個数 for i := 1 to Top do begin for j := 1 to Top - i do Write(' '); for j := 1 to Len do Write('o'); Writeln; Len := Len + 2; end; Readln; end.
次の三角形を表示させるプログラム
o o o o o ooooooo
var i, j, Top, Len: Integer; begin Len := 1; Top := 4; for i := 1 to Top do begin for j := 1 to Top - i do Write(' '); for j := 1 to Len do begin if i = Top then Write('o') else if j = 1 then Write('o') else if j = Len then Write('o') else Write(' '); end; Writeln; Len := Len + 2; end; Readln; end.
上のコードの別解として次のコードがあります。
var i, j, Top, Len: Integer; begin Len := 1; Top := 4; for i := 1 to Top do begin for j := 1 to Top - i do Write(' '); for j := 1 to Len do if (i = Top) or (j = 1) or (j = Len) then Write('o') else Write(' '); Writeln; Len := Len + 2; end; Readln; end.
更新日:2004-12-08