こんにちは、ナナです。
前回のデバッグ技術の記事『初心者向けデバッグ技術【プログラムが動かない悩み解決】』では、プログラムをする上での基礎的なデバッグ方法を解説しました。
新しく『関数』という概念を手に入れたのであれば、さらなるデバッグ技術を手に入れましょう。
本記事では次の疑問点を解消する内容となっています。
では、『デバッガ』の使い方を解説していきましょう。
デバッグ技術 Level2:『ステップイン』と『ステップアウト』機能
前回「Level1」で学んだデバッグ技術は最低限の基礎的なものでした。「Level2」ではもう少し踏み込んだデバッグ手法について解説していきましょう。
「Level2」の読者としては、次の人を対象としています。
ステップ実行の種類:『ステップイン』と『ステップアウト』
「ステップ実行」には『ステップオーバー』以外にも種類があります。
各ステップ実行の機能は次のものになります。正しく使うためには、「関数」の概念を理解しておく必要があります。
No | ステップ実行の種類 | 説明 |
---|---|---|
① | ステップイン | 次の行へ実行を進める。 ただし、関数呼び出しの場合は関数の中に実行を進める。 |
② | ステップオーバー | 次の行へ実行を進める。 関数呼び出しの場合でも、関数の中には入らない。 |
③ | ステップアウト | 関数の呼び出し元まで実行を進める。 |
ステップ実行の扱いの違いを知るために、次のプログラムをベースに解説をします。
#include <stdio.h>
unsigned long getTriangleArea(unsigned long bottom, unsigned long height)
{
unsigned long area = 0;
area = bottom * height / 2;
return area;
}
int main(void)
{
unsigned long bottom = 10; // 底辺
unsigned long height = 20; // 高さ
unsigned long area;
area = getTriangleArea(bottom, height);
printf("三角形の面積:%d", area);
return 0;
}
三角形の面積を求めるための、getTriangleArea関数が定義されています。
多くの統合開発環境において、この3つの「ステップ実行」の機能は搭載されています。扱い方は一緒なので、一度使い方を覚えてしまえば、どの環境でも利用できます。
『ステップオーバー』と『ステップイン』の違い
この2つは初心者のうちは区別をつけられないことが多く、「何が違うの?」と迷う方が結構いるんです。
『ステップオーバー』と『ステップイン』は関数呼び出しではない処理を動かす時には、「次の処理にステップ実行をする」という挙動は同じです。
違いが出るのは、次のようにステップ実行が「関数」を呼び出す行に差し掛かったときです。
このように、「関数」の中に処理を進めるのが『ステップイン』、 関数を実行したものとして次の行に進めるのが『ステップオーバー』です。
『ステップイン』の『イン』とは、「関数の中に入る(イン)」という意味なのです。そう理解すると、違いを覚えやすいですね。
『ステップアウト』の使い方
『ステップイン』の意味が分かると『ステップアウト』の意味もわかりますね。『ステップアウト』とは「関数の外に出る(アウト)」という意味です。
関数の中の処理をステップ実行している際に、『ステップアウト』をすると関数の呼び出し元まで実行を進めることになります。
実際の関数は数十行といった大きな処理になっていることも多く、「もうここまでで見るのはOKだから、呼び出し元に処理を移動させたい」というシーンで使います。
これらの『ステップ実行』のコマンドを使いこなしながら、デバッグ作業を効率よく行うことです。
「効率よく」というのは、最初からできるわけでないので、少しずつ使いながら作業に慣れていく必要があります。積極的にステップ実行を使って慣れていくことです。
デバッグ機能:ウォッチ画面で「グローバル変数」の値を確認する
前回の記事にて紹介した「ローカル」画面とは、実は「ローカル変数」を表示するための機能だったんです。
そのため、この画面には「グローバル変数」が表示されません。グローバル変数を確認するためにはどうしたらよいのでしょう。
変数の値を確認するための「ローカル」画面には、実行対象の関数で定義された『ローカル変数』の一覧が表示されてます。
この画面には『グローバル変数』は表示されません。
何でも表示できる便利な「ウォッチ」画面とは
次のように、グローバル変数が定義されていたとしましょう。
#include <stdio.h>
// グローバル変数で管理する面積
unsigned long gArea = 0;
unsigned long getTriangleArea(unsigned long bottom, unsigned long height)
{
unsigned long area = 0;
area = bottom * height / 2;
return area;
}
int main(void)
{
unsigned long bottom = 10; // 底辺
unsigned long height = 20; // 高さ
gArea = getTriangleArea(bottom, height);
printf("三角形の面積:%d", gArea);
return 0;
}
Visual Studioで動かすとわかりますが、「ローカル」画面の中にはグローバル変数は表示されません。
『グローバル変数』の値を確認するためには、「ウォッチ」画面を使います。
「ウォッチ」画面の特徴は、自分で登録する必要がありますが、グローバル変数はもちろん、数式といった演算も含めて様々な情報を登録できることです。
その利用範囲は「変数」にとどまりません。数式や判定式など様々な情報を任意に登録することができる、めちゃくちゃ便利な機能です。
「ウォッチ」画面の表示切り替えタブがないという方は、こちらのメニューから表示を有効にすることが可能です。
デバッグに関わる画面はこのメニューから表示ができることを覚えておくとよいです。「ウォッチ」以外にも様々なデバッグ機能があることがわかりますね。
多くの初心者にウォッチ画面の使い方を教えると「こんなことできるんですか!」って驚きます。
結局便利さを知らないと人は使わないんです。だから、使ってみて便利さを知ることですよ!
『脳内デバッグ』鍛錬への道
この記事を見るレベルに達しているプログラミング初心者の方には、絶対にやってほしいことがあります。
それは自分の作ったプログラムを順に動かしながら考察することです。
『脳内デバッグ』とは何なのか?
『脳内デバッグ』
それは、『デバッガ』を使わずして、デバッガ相当の動きを頭の中でイメージする技術です。
経験豊かな開発者は、この技術を備えています。しかし、それは天賦の才などではなく、努力と訓練によって鍛え上げられた技術なんです。
実際の開発の現場では、こんな人は結構たくさんいます。
初心者の人は「なんでこんなにすぐにわかるの?」と思うかもしれませんが、それは頭の中でプログラムを動かすことができるからなんです。
『脳内デバッグ』への険しい道のり
この『脳内デバッグ』ができるようになると、プログラムスピードが断然速くなります。しかし、こんなものは初心者がすぐにできるような代物ではありません。
『脳内デバッグ』習得の道とは、地道な鍛錬と共に進む道なのです。
さぁ、プログラミング技術を向上させたい人は、少しずつでも鍛錬を行いましょう。
『脳内デバッグ』の鍛錬方法
本サイトの入門カリキュラムには様々なプログラムの課題が用意されています。その時に皆さんに実施してもらいたいことがあります。
それは
プログラムの先頭から順に、『ステップ実行』を使ってプログラムがどんな風に動くのかを真剣に考察する
ことです。
『ステップ実行』の良さとは、プログラムが動く流れを可視化できることです。
プログラム初心者の方はまず、プログラムというものがどのように動いているのかを『ステップ実行』をしながら感じることから鍛えていきます。
これを繰り返すことで、プログラムの動きを確実に理解できるようにしていきます。変数の値も頭の中でイメージしながら、見ていく力を鍛えていきます。
この作業を繰り返すことで『脳内デバッグ』が自然とできるようになっていきます。
デバッグ技術の「Level3」は『ポインタのデバッグ メモリを可視化する【初心者向け】』の記事で紹介しています。ポインタが学び終わった方は是非見ておくことをオススメします。