Day 61 のゴールと全体像
Day 61 では、いよいよ「デバッグ」という、実践力を一気に底上げしてくれるテーマに踏み込んでいきます。 コードを書く力ももちろん大事ですが、「バグを見つけて直す力」こそが、現場で頼られるエンジニアの武器になります。
今日のキーワードは次の4つです。
- ブレークポイント
- ステップ実行
- 変数確認
- コールスタック
どれも Visual Studio などの統合開発環境(IDE)でよく使う機能で、 「なんだか難しそう…」と感じる方もいるかもしれませんが、 一度“使い方の筋道”が見えてくると、むしろ手放せない相棒になってくれます。
ここでは、初心者の方でもイメージしやすいように、 小さなサンプルコードを題材にしながら、 デバッグの流れをステップバイステップで追いかけていきます。
デバッグの全体イメージをつかむ
デバッグって何をする時間?
デバッグは、ざっくり言うと次のような時間です。
- コードが「どんな順番で」動いているかを観察する
- 変数に「どんな値」が入っているかを確認する
- 想定と違う動きをしている箇所を特定する
- 原因を見つけて、修正する
つまり、プログラムの中で起きていることを“見える化”する作業と言ってもいいです。
そのための道具が、
- ブレークポイント
- ステップ実行
- 変数確認
- コールスタック
という4つの機能です。 これらを組み合わせることで、 「プログラムの中をゆっくり歩きながら、様子を観察する」ことができるようになります。
例題コード:ちょっとバグのある合計計算
まずは、デバッグの練習台になる小さなコードを用意します。
using System;
class Program
{
static void Main()
{
int[] numbers = { 1, 2, 3, 4, 5 };
int total = CalculateTotal(numbers);
Console.WriteLine($"合計は {total} です。");
}
static int CalculateTotal(int[] values)
{
int sum = 0;
// わざとバグを仕込んでみます(最後の要素を足し忘れている)
for (int i = 0; i < values.Length - 1; i++)
{
sum += values[i];
}
return sum;
}
}
C#このコードは、
numbersに{1, 2, 3, 4, 5}を入れてCalculateTotalで合計を計算し- 結果を表示する
というシンプルなものです。
しかし、for 文の条件が i < values.Length - 1 になっているため、 最後の要素(5)が合計に含まれないというバグがあります。
実行すると、
合計は 10 です。
と表示されてしまい、本来の合計 15 と違う結果になります。 この「どこかおかしいぞ?」という状態を、デバッグで追いかけていきます。
ブレークポイント ― プログラムを一時停止させる
ブレークポイントとは
ブレークポイントは、
「ここで一度止まってね」とプログラムに指示するための印
です。
Visual Studio では、
- コードの左側の余白(行番号の近く)をクリックすると
- 赤い丸が付き、その行にブレークポイントが設定されます
プログラムを「デバッグ実行」すると、 その行に到達したタイミングで、プログラムが一時停止します。
どこにブレークポイントを置くとよいか
今回の例では、バグがありそうなのは CalculateTotal の中です。 なので、まずはこのメソッドの先頭にブレークポイントを置いてみます。
static int CalculateTotal(int[] values)
{
int sum = 0; // ← この行にブレークポイントを置く
C#こうしておくと、
MainからCalculateTotal(numbers)が呼ばれた瞬間sum = 0;の行でプログラムが止まる
という状態になります。
ブレークポイントの役割の深掘り
ブレークポイントは、
- 「怪しいと思う場所」
- 「処理の入口」
- 「ループの中」
などに置いて、 その行に到達したときの状態を観察するための“観測点”として使います。
闇雲にたくさん置くのではなく、 「ここで止まると、何が分かりそうか?」を意識して置くと、 デバッグがぐっとスムーズになります。
ステップ実行 ― 1行ずつゆっくり進める
ブレークポイントでプログラムを止めたら、 次は「ステップ実行」で、1行ずつゆっくり進めていきます。
ステップ実行の種類
代表的なステップ実行は次の3つです。
- ステップオーバー(Step Over)
- 現在の行を実行して、次の行に進む
- メソッド呼び出しがあっても、その中には入らない
- ステップイン(Step Into)
- 現在の行を実行し、メソッド呼び出しがあればその中に入る
- ステップアウト(Step Out)
- 現在のメソッドの残りを一気に実行し、呼び出し元に戻る
Visual Studio では、
- F10 → ステップオーバー
- F11 → ステップイン
というキーがよく使われます(設定によって違う場合もあります)。
例題コードでステップ実行してみる
ブレークポイントで sum = 0; の行に止まった状態から、 ステップオーバーで進めてみます。
static int CalculateTotal(int[] values)
{
int sum = 0; // ここで停止中
for (int i = 0; i < values.Length - 1; i++)
{
sum += values[i];
}
return sum;
}
C#sum = 0;の行で止まる- ステップオーバーすると、
sumに0が入る - 次の行
for (int i = 0; i < values.Length - 1; i++)に移る - さらにステップオーバーすると、ループの中に入る
ループの中では、
sum += values[i];
C#の行で止まりながら、
iがいくつかvalues[i]がいくつかsumがいくつになったか
を、1回ずつ確認していくことができます。
ステップ実行の大事な感覚
ステップ実行は、
「プログラムの中を、1行ずつ歩いていく」
ようなイメージです。
- どの行がいつ実行されているか
- ループが何回回っているか
- 条件分岐がどちらの道に進んでいるか
を、目で見て追いかけられるようになると、 「なんとなく動いている」から「ちゃんと理解して動かしている」に変わっていきます。
変数確認 ― 今この瞬間の中身を見る
ステップ実行をしているときに、 ぜひセットで使いたいのが「変数確認」です。
変数の中身を確認する方法
Visual Studio では、
- 変数名の上にマウスカーソルを乗せると、 現在の値がポップアップで表示されます
- 「ローカル」ウィンドウや「ウォッチ」ウィンドウに変数を追加して、 値の変化を追いかけることもできます
例題コードの CalculateTotal をステップ実行しながら、
ivalues[i]sum
の3つを確認してみると、 ループがどんなふうに動いているかが、はっきり見えてきます。
実際に追いかけてみるイメージ
values = {1, 2, 3, 4, 5} のとき、
- 1回目のループ
i = 0values[i] = 1sumは0 + 1 = 1
- 2回目のループ
i = 1values[i] = 2sumは1 + 2 = 3
- 3回目のループ
i = 2values[i] = 3sumは3 + 3 = 6
- 4回目のループ
i = 3values[i] = 4sumは6 + 4 = 10
ここで、
i < values.Length - 1→i < 4
なので、i = 4 のループは実行されません。 つまり、values[4] = 5 が足されないまま、sum = 10 で終わってしまいます。
この「最後の要素が足されていない」という事実は、 変数確認をしながらステップ実行することで、はっきりと目に見える形で理解できます。
変数確認の重要ポイント
- 「想定している値」と「実際に入っている値」が違うとき、 バグの手がかりになります。
- ループや条件分岐の中で、変数がどう変化しているかを追いかけることで、 「どこからおかしくなっているか」が見えてきます。
変数確認は、 プログラムの“心の声”を聞くようなイメージで使ってみると、 少し楽しくなってきます。
コールスタック ― 「誰が誰を呼んだか」の履歴
最後に、少し概念的ですが、とても大事な「コールスタック」を見ていきます。
コールスタックとは
コールスタックは、
「今の行にたどり着くまでに、どのメソッドがどの順番で呼ばれてきたか」
を示してくれる“呼び出し履歴”のようなものです。
Visual Studio では、
- デバッグ中に「コールスタック」ウィンドウを開くと
- 上から順に「現在のメソッド → その呼び出し元 → さらにその呼び出し元…」 という形で表示されます
例題コードでのコールスタック
例題コードをデバッグしているとき、 CalculateTotal の中で止まっているとします。
そのときのコールスタックは、だいたいこんな感じになります。
CalculateTotal(int[] values)Main()
これは、
- 今は
CalculateTotalの中にいて - その呼び出し元は
Mainである
ということを示しています。
もし、
Main→ProcessData→CalculateTotal
というように、メソッドが何段階もネストして呼ばれている場合、 コールスタックを見ることで、
- 「今どの階層にいるのか」
- 「どのメソッドからここに来たのか」
を把握することができます。
コールスタックが役立つ場面
- 例外が発生したとき
- 「どのメソッドで例外が起きたか」
- 「そのメソッドはどこから呼ばれていたか」 を知る手がかりになります。
- 複雑な処理の流れを追いたいとき
- 「このメソッドは、どこから呼ばれているのか?」 を確認することで、全体像をつかみやすくなります。
コールスタックは、 プログラムの“足跡”をたどるための地図のような存在です。
バグを直してみる ― デバッグから修正へ
ここまでの流れで、
- ブレークポイントで
CalculateTotalの入口に止まり - ステップ実行でループを1回ずつ追いかけ
- 変数確認で
sumやiの値を見て - 「最後の要素が足されていない」という事実に気づく
というところまで来ました。
では、実際にバグを直してみます。
修正前
for (int i = 0; i < values.Length - 1; i++)
{
sum += values[i];
}
C#修正後
for (int i = 0; i < values.Length; i++)
{
sum += values[i];
}
C#values.Length - 1 を values.Length に直すことで、 i は 0 から 4 まで回り、
1 + 2 + 3 + 4 + 5 = 15
という正しい合計が求められるようになります。
修正後にもう一度デバッグして、
- ステップ実行でループを追いかけ
- 変数確認で
sumの変化を見て
「今度はちゃんと最後の要素まで足されている」と確認できれば、 バグ修正完了です。
デバッグのミニテンプレート
最後に、デバッグの流れをざっくりテンプレートとしてまとめておきます。
- おかしい結果に気づく
- 「想定していた値と違う」
- 「例外が出る」
- 怪しい箇所にブレークポイントを置く
- 計算処理の入口
- ループの中
- 条件分岐の前後
- ステップ実行で1行ずつ進める
- ステップオーバーで流れを追う
- 必要に応じてステップインでメソッドの中に入る
- 変数確認で中身を観察する
- 「想定している値」と「実際の値」を比べる
- ループ回数や条件分岐の道を確認する
- コールスタックで呼び出し関係を把握する
- どのメソッドからここに来たかを確認する
- 原因を特定して、コードを修正する
- 条件式のミス
- ループ範囲のミス
- 代入漏れ・初期化漏れ など
- もう一度デバッグして、直ったことを確認する
この流れに慣れてくると、 「バグが怖いもの」から「ちょっとしたパズル」くらいの感覚に変わっていきます。
Day 61 のまとめ
Day 61 では、
- ブレークポイントで「ここで止まってね」とプログラムに指示し
- ステップ実行で1行ずつゆっくり進めて
- 変数確認で「今この瞬間の中身」を見て
- コールスタックで「誰が誰を呼んだか」の履歴をたどる
という、デバッグの基本的な流れを学びました。
デバッグは、最初は少しとっつきにくく感じるかもしれませんが、 「プログラムの中を散歩する感覚」で触ってみると、だんだん楽しくなってきます。
ぜひ、
- 自分のコードにわざと小さなバグを仕込んでみる
- ブレークポイントとステップ実行で「どこがおかしいか」を探してみる
- 変数確認とコールスタックを使って、プログラムの流れを眺めてみる
といった小さな練習を重ねながら、 「バグと仲良くなる」感覚を育てていっていただければうれしいです。

