想定外の現象 : 論理エラーの検出

更新 : 2007 年 11 月

このレッスンでは、プログラム内の論理エラーを検出する方法について説明します。

前のレッスンでは、コンパイラ エラーおよびランタイム エラーを検出して修正する方法について説明しました。3 種類目のプログラミング エラーは、論理エラーで、検出が最も困難なエラーです。論理エラーの場合、警告は一切出ません。プログラムは動作しますが、結果は間違っています。それからコードを精査して、問題が発生した理由を調べる必要があります。

これには、Visual Basic のデバッグ ツールが役立ちます。ブレークポイントの設定とコードのステップ実行の 2 つのデバッグ手法により、実行中にコードを 1 行ずつ調べて、エラーを検出できます。

実行できるコード行いずれに対しても、コード エディタでブレークポイントを設定できます。プログラムを実行してブレークポイントのコード行に達すると、実行が強制的に停止され、中断モードに入ります。そして、その時点でのプログラムの状態について、必要な情報を取得できます。変数の値を確認したり、[イミディエイト] ウィンドウで式をテストしたり、エディット コンティニュを使用してコードを変更したりできます。

中断モードに入ると、コードをステップ実行、つまり 1 行ずつ実行して、コードがどのように動作するかを確認できます。F8 キーを押すと、現在のコード行が実行され、次の行で停止します。その時点で、変数の値を調べて、次の行に移動する間に値がどのように変化するかを確認できます。

現在のコード行が、コード内の他の場所の関数または Sub プロシージャを呼び出している場合、F8 キーを押すと、実行はそのプロシージャにステップ インします。プロシージャのステップ実行が終わると、そのプロシージャを呼び出した行の次の行に戻ります。プロシージャをステップ実行しない場合は、Shift キーを押しながら F8 キーを押して、プロシージャをステップ オーバーします。

やってみよう

論理エラーを検証するには

  1. [ファイル] メニューの [新規作成] をポイントし、[プロジェクト] をクリックします。

  2. [新しいプロジェクト] ダイアログ ボックスの [テンプレート] ペインで、[Windows アプリケーション] をクリックします。

  3. [プロジェクト名] ボックスに「LogicErrors」と入力し、[OK] をクリックします。

    新しい Windows フォーム プロジェクトが開きます。

  4. ツールボックスから、フォームに 2 つの TextBox コントロールと 1 つの Button コントロールをドラッグします。

  5. Button1 をダブルクリックしてコード エディタを開きます。

  6. Button1_Click イベント ハンドラに次のコードを追加します。

    Dim minutes As Integer = CInt(Textbox1.Text)
    Dim miles As Double = CDbl(Textbox2.Text)
    Dim hours As Double = 0
    hours = minutes / 60
    MsgBox("Average speed " & GetMPH(hours, miles))
    
  7. End Sub 行の下に次の関数を追加します。

    Function GetMPH(ByVal miles As Double, ByVal hours As Double) _
    As String
        GetMPH = CStr(miles / hours)
    End Function
    
  8. F5 キーを押してプログラムを実行します。最初のテキスト ボックスに「10」(10 分を表す) と入力し、2 番目のテキスト ボックスに「5」(5 マイルを表す) と入力して、Button1 をクリックします。

    メッセージ ボックスに "Average speed 0.03333334" というメッセージが表示されます。しかし、5 マイルを 10 分で移動する場合、正しい答えは 30 mph です。

    プロジェクトは開いたままにしておいてください。次の手順で、論理エラーを検出する方法について説明します。

論理エラーの検出

前の例では、プログラムのロジックに明白な間違いがあります。1 時間あたり 30 マイル移動したはずが、この結果では、1 時間あたり 1 マイル未満しか移動していないことになります。どこにエラーがあるのでしょうか。

次の手順では、ブレークポイントを設定してコードをステップ実行し、エラーを検出します。

やってみよう

ブレークポイントを設定してコードをステップ実行するには

  1. コード エディタで行 hours = minutes / 60 を探し、そのコード行の左マージンをクリックします。

    マージンに赤い点が表示され、コードが赤で強調表示されます。これはブレークポイントを示します。

  2. F5 キーを押して再度プログラムを実行します。最初のテキスト ボックスに「10」、2 番目のテキスト ボックスに「5」と入力します。次に Button1 をクリックします。

    ブレークポイントに達すると、プログラムが停止します。行 hours = minutes / 60 が黄色で強調表示されます。

    変数の値の上にマウスを置いて、値を調べます。hours の値は 0、minutes の値は 10 になります。

  3. F8 キーを押して行 hours = minutes / 60 を実行し、次の行に進みます。

    行 MsgBox("Average speed " & GetMPH(hours, miles)) の変数の値を調べます。hours の値は 0.166666672、miles の値は 5.0 になります。

  4. F8 キーを再度押して、現在の行を実行します。

    実行が行 Function GetMPH に進みます。

    この行で変数の値を調べます。前の行とは逆に、miles の値が 0.166666672 になり、hours の値が 5.0 になっています。エラーが検出されました。

    プロジェクトは開いたままにしておいてください。次の手順で、論理エラーを修正する方法について説明します。

論理エラーの修正

前の手順では、変数 miles と hours の値の位置が入れ替わっていました。原因がわかりますか。

行 MsgBox("Average speed " & GetMPH(hours, miles)) を見ると、GetMPH 関数に 2 つの引数 hours および miles がこの順序で渡されています。関数宣言 Function GetMPH(ByVal miles As Double, ByVal hours As Double)... を見ると、引数は miles、hours の順になっています。

引数が間違った順序で渡されたため、論理エラーが発生し、間違った計算が行われました。引数の型が異なっていれば、ランタイム エラーが発生したと思われますが、引数の型が同じだっため、ランタイム エラーは発生しませんでした。単純な間違いでしたが、その結果発生したバグは、検出するのが困難でした。

次の手順では、ブレークポイントを設定してコードをステップ実行し、エラーを検出します。

やってみよう

論理エラーを修正するには

  1. コード エディタで、行 MsgBox("Average speed " & GetMPH(hours, miles)) を次のように変更します。

    MsgBox("Average speed " & GetMPH(miles, hours))
    
  2. 左マージンの赤い点をクリックして、ブレークポイントを解除します。

  3. F5 キーを押してプログラムを実行します。最初のテキスト ボックスに「10」、2 番目のテキスト ボックスに「5」と入力します。次に Button1 をクリックします。

    今度は、正しい結果である "Average speed 30" を表示するメッセージ ボックスが表示されます。

    プログラムは修正されたように見えますが、検出がさらに困難な論理エラーが存在します。この論理エラーの検出を試みる場合は、プロジェクトを開いたままにしておいてください。レッスン「別のバグ : 他のエラーを発見する」でプロジェクトを再び使用します。

次の手順

このレッスンでは、論理エラーを検出して修正する方法について説明しました。ここで、コメントの使用に関する次のレッスンに進むか、「別のバグ : 他のエラーを発見する」で別の論理エラーを検出してみるかを選択できます。

次のレッスン : 「プログラムの注釈 : コメントを使用する

参照

処理手順

ランタイム エラーの検索と除去

バグの理解 : 3 種類のプログラミング エラー

エラーの検出 : Visual Basic のデバッグの概要