この連載では、Web アプリ JSVisualizer を使って、プログラムの動きを目で見ながらアルゴリズムを 1 つずつ理解していきます。ツールの全体像は第 0 回で紹介しました。
第 1 回のテーマは for ループ と 累積和(数を次々に足し合わせていく計算)です。主役は 変数ビュー です。
よくあるつまずき
次のコードは、1 から 5 までの合計を求めます。
let sum = 0;
for (let i = 1; i <= 5; i++) {
sum = sum + i;
}
console.log(sum);
答えは 15 です。でも、プログラミングを習い始めたばかりの人は、こんなところで引っかかりがちです。
-
sum = sum + iが変に見える。数学なら「sumとsum + iが等しい」はおかしな式です。プログラムでは=は「右側を計算して、その結果を左側の変数に入れ直す」という意味(代入)ですが、それが頭ではわかっていても、実感がわかない -
for (...; ...; ...)の 3 つの部分が、どの順番で実行されるのかがわからない。i++はいつ実行されるのか、i <= 5はいつ確かめられるのか -
ループが終わったとき
iはいくつなのか。5 回繰り返すのだから 5?
授業では、こうしたことを確かめるために「トレース表」を手で書くことがあります。行ごとに変数の値を書き込んで、値が変わるたびに書き直していく表です。わかりやすい方法ですが、書くのが面倒で、書き間違えると混乱のもとにもなります。
JSVisualizer の変数ビューは、この表をプログラムを実行しながら自動で作ってくれるビューです。
変数ビューで見る
見方
上のコードを JSVisualizer に貼り付けて「▶ 実行」を押し、「変数」タブを開きます。上部の「人▷」ボタン(人にやさしい単位で 1 ステップ進める。代入や条件判定など、意味のある変化ごとに止まる)を 3 回押すと、次のようになります。
-
行: ソースコードの各行です。いま実行している行(ここでは 2 行目の
for)が青くなっています -
列: プログラムに出てくる変数(
sum・i)です。変数が作られると列が増えます -
一番右の列: ループの条件式
i <= 5の結果です - セルの値: その行を最後に実行したときの変数の値です。まだ実行していない行は「—」です
1 行目で sum が 0 になり、2 行目で i が 1 になって、条件 i <= 5 が true になった — ここまでがひと目でわかります。
ステップを進める
さらに「人▷」を 5 回押します(合計 8 回)。
2 行目の i が 3 になり、オレンジ色で強調されています。オレンジは「今のステップで値が変わった」という印です。
ここで 3 行目を見てください。3 行目の i は 2 のままです。3 行目 sum = sum + i を最後に実行したのは i が 2 のときで、そのとき sum は 1 + 2 = 3 になった、ということです。その後 2 行目に戻って i++ が実行され、i が 3 になった — 同じ変数でも、行によって「最後に見た値」が違うので、実行の順番が表から読み取れます。
最後まで進める
最後まで進めると(キーボードの End キーで一気に飛べます)、こうなります。
下のコンソールに 15 が出力され、合計が正しく求められました。表からは、それ以上のことも読み取れます。
気づき
1. i++ は本体の「後」に実行される
ステップを進めながら 2 行目と 3 行目を見比べると、3 行目の i はいつも 2 行目の i より 1 小さいことに気づきます。for ループの実行順はこうなっているからです。
-
let i = 1(最初の 1 回だけ) -
i <= 5を確かめる →trueなら本体へ、falseなら終了 - 本体
sum = sum + iを実行する -
i++を実行して、2 に戻る
i++ は for の行の一番右に書いてありますが、実行されるのは本体の後です。
2. ループが終わったとき、i は 6
最後の表で、2 行目の i は 6、条件 i <= 5 は false です。一方、3 行目の i は 5 です。
本体は i が 1, 2, 3, 4, 5 のときの 5 回だけ実行されますが、i 自体は 6 まで進みます。6 になって条件が false になったから、ループを抜けたのです。「i <= 5 を i < 5 に変えたらどうなる?」という問題を考えるときにも、この見方が役に立ちます。
3. ループの外では i は存在しない
5 行目 console.log(sum) の行で、i の欄は「—」です。for (let i = 1; ...) の let で作った i は for ループの中だけで使える変数なので、ループを抜けると消えてしまいます。もし 5 行目を console.log(i) にすると、コードの下に「Runtime Error … 未定義の変数: 'i'」と表示されます(試してみてください)。
4. sum = sum + i は「入れ直し」
3 行目の sum は、ステップを進めるたびに 1 → 3 → 6 → 10 → 15 と書き換わっていきます。= は「等しい」ではなく「右辺を計算して、左の変数に入れ直す」という操作だということが、値が置き換わる様子を見ると実感できます。
補足: 全部の履歴を見たいときは「実行トレース」
変数ビューは「各行の最新の値」を見せるので、表がコードと同じ行数で収まり、コードと見比べやすいのが長所です。一方で、過去の値は上書きされて消えていきます。
すべてのステップの値を縦に並べて見たいときは、「実行トレース」タブが便利です。手書きのトレース表を全部書き出したものに近い表になります。
sum が 0 → 1 → 3 → 6 → 10 → 15 と増え、最後に i が 6 になって条件が false になる流れが、上から下へ一度に読めます。実行トレースは連載の後半(二分探索の回)で主役として取り上げます。
自分で試してみよう
このリンクを開いて「▶ 実行」を押すと、変数ビューが開きます。「人▷」(キーボードの h)で 1 ステップずつ進め、「◁人」(H)で戻れます。
▶ JSVisualizer で開く(1 から 5 までの合計・変数ビュー)
コードを書き換えるには「✏ 編集」を押します。こんなふうに変えて、表がどう変わるか予想してから実行してみてください。
-
i <= 5をi < 5にする → 合計は? ループを抜けたときのiは? -
i++をi += 2にする → どの数が足される? -
sum = sum + iをsum = sum * iにして、sumの最初の値を1にする → 何が求まる?
まとめと次回予告
- 変数ビューは、ソースの各行の横に「その行を最後に実行したときの変数の値」を並べた表。手書きのトレース表を自動で作ってくれる
- 値が変わったところはオレンジで強調されるので、ステップごとに何が起きたかがわかる
- 行どうしを見比べると、for ループの実行順(条件 → 本体 →
i++)や、ループを抜けたときのiの値まで読み取れる
次回(第 2 回)は 条件分岐(if / else if / else)を取り上げます。点数から成績を判定するコードを 制御フロービュー で動かし、「どの分岐を通って、どの分岐を通らなかったか」をフローチャートで確かめます。



