デバッグ機能の基本
デバッグとは
プログラムミングは「こういう動作をして欲しい」とあらかじめ決めてから、その通りの動作をするようにコードを記述していきます。
しかし時に期待通りに動作しないことがあります。
これはコードが間違っているということですが、どこがどう間違っているのかが分からないということがあります。
数行程度のコードならばコードよく見直せば発見できるかもしれませんが、数十、数百行ものコードとなると間違っている個所を探し出すだけでも大変です。
Visual Studioではこのようなコードの間違いを発見、修正するための機能があります。
これをデバッグ機能といいます。
以下はC#の説明というよりもVisual Studioの使い方の説明です。
Visual Studio以外でも開発環境を使用しているならデバッグ機能が搭載されていると思うので、各自で調べてください。
Visual Studioではデバッグモードで実行中にデバッグ機能が使用できます。
リリースモードはプログラムを第三者に配布する場合のモードで、デバッグに関する情報が省かれます。
(その分ファイルサイズが小さくなり、速度も優れる)
開発中はデバッグモードで実行してください。
まれに、使用しているライブラリのバグで動作がおかしいということはあります。
しかし滅多にあることではないので、うまく動作しない場合はまずは自分で書いたコードの間違いを疑うべきです。
(.NET Framework標準のライブラリを使用しているならなおさら)
Visual Studioのデバッグ機能
以下の画像の青色部の面積をプログラミングで計算してみましょう。
(円は正円です)
以下のようなコードを書いたとします。
static void Main(string[] args)
{
//正方形の一片の長さ
int side = 5;
//正方形の面積
int areaSquare = side * side;
//円の面積
double areaCircle = (side / 2) * (side / 2) * 3.14;
//青色部の面積
double areaBlue = areaSquare - areaCircle;
Console.WriteLine(areaBlue);
Console.ReadLine();
}
まず正方形の面積を算出し、次に円の面積を算出します。
そして円の面積を正方形の面積から引けば答えになります。
このコードの計算結果は以下です。
12.44
さてこれは本当に正しいでしょうか?
電卓をたたいて計算してみると、正しくは「5.375」です。
パっと見ただけでも青色部分は正方形面積の半分よりもっと少ないですよね。
しかしコードを見直してみても何が間違いなのかがよくわかりません。
そんな時はデバッグ機能を使用すると間違いの発見が容易になります。
まず、Visual Studioのコードエディタ上で、間違いがありそうな行の左端のエリアをクリックします。
(画像のマウスポインタのあたり)
すると赤い丸印がつけられ、その行が赤くハイライトされます。
この赤丸の点をブレークポイントといいます。
なお、「F9」キーで現在の行にブレークポイントを設置することもできます。
この状態で、デバッグモードでプログラムを実行します。
すると、ブレークポイントの行を実行する直前でプログラムの実行が停止します。
以下は変数areaSquare
には値はまだ何も入っていない状態です。
次に実行される行の左端には黄色い矢印が表示されます。
(この行はまだ実行されていません)
ブレークポイントで停止中は、Visual Studioの画面下部に「ローカル」というウィンドウが表示されます。
もし表示されていない場合は「デバッグ」メニュー→「ウィンドウ」→「ローカル」から表示してください。
この「ローカル」ウィンドウには現在実行中のコードにある変数とその中身の一覧が表示されます。
(正確に言えばローカル変数とメソッドの引数が表示される)
ブレークポイントで停止中は、「F10」キーでコードを一行ずつ実行可能です。
これをステップ実行といい、「F10」キーはステップオーバーという実行方法です。
「デバッグ」メニュー内からでも実行できますが、F10キーのほうが圧倒的に早いので覚えてしまいましょう。
試しに上記状態から一回だけF10キーを押してみます。
先ほどのint areaSquare = side * side;
の行が実行され、変数areaSquare
には計算結果が代入されます。
代入の結果はローカルウィンドウで確認できます。
(直前の実行で値が変化した変数は赤色で表示されます)
このように、コードを一行ずつ実行して変数の値の変化をチェックできるので、間違いを見つけるのに役立ちます。
ちなみにこのコードの間違いは円の面積の算出方法です。
そのままもう一度ステップ実行してみると、変数areaCircle
には「12.56」が入ります。
正方形の面積の半分ほどしかありませんから、明らかに小さいですよね。
(実際に実行してみて確かめてみてください)
円の面積を求める公式自体は間違っていないのですが、実は円の半径を求める段階で間違った値になっています。
int型は整数型を扱うデータ型で、小数は扱えません。
コード中に直接記述される整数(今回は「2」)は、特別な指定をしなければint型となります。
そして、int型同士の割り算の結果はint型になります。
これらの性質から、「5÷2」の計算結果は「2.5」ではなく、小数以下は切り捨てられて「2」になってしまうのです。
実際に以下のコードを書いて確かめてみましょう。
int num = 5 / 2; //←2
//演算の時点ですでにint型なので
//double型で受け取ってもダメ
double real = 5 / 2; //←2
Console.WriteLine(num);
Console.WriteLine(real);
2 2
コードの間違いを直したのが以下です。
static void Main(string[] args)
{
//正方形の一片の長さ
int side = 5;
//正方形の面積
int areaSquare = side * side;
//円の面積
double areaCircle = (side / 2.0) * (side / 2.0) * 3.14;
//青色部の面積
double areaBlue = areaSquare - areaCircle;
Console.WriteLine(areaBlue);
Console.ReadLine();
}
5.375
コード中に直接記述する値を「2」から「2.0」に変更しただけです。
一見意味がないように思えますが、数値に小数点を記述するとその値はdouble型であるとみなされます。
これで「int型÷double型」の演算になり、計算結果はdouble型になるので、正しい結果が得られるようになります。
ステップインとステップオーバー
デバッグの実行方法にはステップインとステップオーバーの二種類があります。
これらはメソッドに関係するステップ実行の機能なので、ステップインによるメソッド内部のデバッグの項で改めて解説します。
コンパイルエラーと実行時エラー
プログラムでは大まかにコンパイルエラーと実行時エラーの二種類のエラーがあります。
コンパイルエラーはコードの文法上の間違いで、コンパイル自体ができません。
実行時エラーは、コンパイルとプログラムの実行は可能ですが、プログラム実行時に処理の継続が不可能になるエラーです。
コンパイルエラーは、Viaual Studioがエラーの箇所とメッセージ(英語ですが)を表示してくれるため、比較的対処しやすいでしょう。
実行時エラーは、Viaual Studioのデバッグモードで実行しているときはエラーの箇所でプログラムが停止し、ブレークポイントを設置した時と同じようにその時点での変数の中身等を確認することができます。
(ただし、実行時エラーが発生した箇所とは微妙に異なる場所が強調表示される場合もあります)
デバッグ機能でエラーの原因を修正するのが基本ですが、実行時エラーはプログラム側では対処しきれない場合があります。
例えばメモリ操作やファイル操作などでは、プログラムには問題がなくてもプログラム外部の問題で実行時エラーが発生することがあります。
このような実行時エラーは例外処理という方法で対処可能です。