小さなプログラムをデバッグする方法

StackOverflowで表示される非常に少数の悪い質問は、次の式で説明できます。

これが私の宿題の解決策です。 機能しません。

[20行のコード]

そして...それだけです。



ご注意 transl .:これは、英語のStackOverflowのリファレンスセクションで参照されている、最小限の、自給自足の、再現可能なサンプルの作成に特化した記事「 How to debug小さいプログラム 」の翻訳です。 すべてのプログラマーが知っておくべきこと-動作しないコードのデバッグの基本-を完全に説明しているように思えます。



このメモを読んでいる場合、この質問が閉じられて削除される直前に、私または他の誰かがStackOverflowの質問の下に残したリンクをたどった可能性が高いです。 (別の理由でこのノートを読んだ場合は、コメントに小さなプログラムをデバッグするためのお気に入りのヒントを残してください)。



StackOverflowは質疑応答サイトですが、特定のコードに関する非常に具体的な質問用です。 「修正できないバグのあるコードを書いた」-これは質問ではなく、 物語であり、あまり面白くない。 「ゼロから単位を引くと、なぜゼロより大きい数が得られるのですか。それが、12行目のゼロとの比較が誤ってtrue



計算される理由です」-これは特定のコードに関する特定の質問です。



したがって、 破損したプログラムの修正をインターネットに依頼します 。 確かにあなたは小さなプログラムをデバッグする方法を教えられたことはありません。なぜなら、 あなたが今していることは最も効果的な方法ではないからです。 StackOverflowはこれを行わないため、今日は自分でコードをデバッグする方法を学ぶのに最適な日です。



以下では、プログラムはコンパイルされますが、正しく動作しないと仮定しています。さらに、この誤った動作を示す例があります。 バグを見つける方法:



まず、 すべてのコンパイラ警告を有効にします 。 20行のコードの正しいプログラムがコンパイラの警告を受け取る理由はありません 。 警告は、コンパイラが「このプログラムはコンパイルしますが、あなたが考えていることはしません」と言ったときです。 これはまさにあなたがいる状況なので、聞いてください。



警告を注意深く読んでください 。 これまたはその警告が発行された理由がわからない場合、これは特定のコードに関する特定の質問であるため、StackOverflowにとって良い質問です 。 質問に正確な警告テキスト、発行された正確なコード、使用しているコンパイラの正確なバージョンを追加します。



プログラムにまだバグがある場合は、ゴム製のアヒルを見つけます 。 近くにゴム製のアヒルがいない場合は、別の学生プログラマーを見つけます-彼とアヒルの間にほとんど違いはありません。 プログラムのすべてのメソッドのすべての行が明らかに正しい理由を、リファイナーに簡単な言葉で説明してください。 ある時点で、あなたが書いたメソッドを理解していないか、エラーがあるか、またはその両方の問題に遭遇します。 この方法に集中してください。 ほとんどの場合、問題はその中にあります。 いいえ、本当に、 アヒルの子の方法は機能します。 そして、伝説的なプログラマーであるレイモンド・チェンが以下のコメントに追加したように( 約。:元の投稿に ):なぜこの行またはその行が必要なのかをアヒルに説明できない場合-おそらくコードを書き始めたためだろうあなたは計画を得た。



プログラムが警告なしでコンパイルされ、アヒルに深刻な質問がなく、まだバグがある場合は、コードを小さなメソッドに分割してみてください。各メソッドは 、それぞれ1つの論理演算を実行ます。 初心者だけでなく、すべてのプログラマーによくある間違いは、一度にいくつかのことを行うメソッドを記述し、それらを不十分に実行することです。 小さな方法は理解しやすく、その結果、あなたとアヒルはエラーに気付きやすくなります。



メソッドをより小さなメソッドにリメイクする場合、各メソッドの技術仕様作成するために少し停止します。 それを1つまたは2つの文にしますが、仕様の可用性が役立ちます。 技術仕様には、メソッドの機能、有効なパラメーター、予期される戻り値、エラーが発生するケースなどを記述する必要があります。 多くの場合、仕様を記述するときに、あるケースを処理するのを忘れたことに気づきます。バグはまさにその中にあります。



それでもバグがある場合は、仕様各メソッドの前提条件と事後条件を記述していることを確認し、再確認してください。 前提条件は、メソッドが機能を開始する前に満たす必要があるものです。 事後条件は、メソッドが作業を終了したときに実行されるものです。 前提条件の例:「引数は有効な非ゼロポインター」、「送信されたリンクリストに少なくとも2つの頂点がある」、または「この引数は正の整数です」。 事後条件の例:「リンクリストには、入力時よりも1つ少ない項目があります」、「配列の特定の部分が現在ソートされている」など。 前提条件に違反した場合、これはメソッドが呼び出された場所のエラーです。 すべての前提条件が満たされたときに事後条件に違反した場合、これはメソッドのエラーです。 繰り返しますが、事前条件と事後条件を定式化するとき、忘れられたケースに遭遇することがよくあります。



バグがまだここにある場合は、事前条件と事後条件をチェックするアサーションを書くことを学びます。 アサーションはコメントのようなもので、条件に違反した場合にそれを伝えるだけです。 そして、違反した状態はほとんど常にバグです。 C# using System.Diagnostics;



言うことができますusing System.Diagnostics;



コードの先頭で、途中でDebug.Assert(value != null);



書きDebug.Assert(value != null);



または類似のもの。 各言語には、ステートメントを定式化するメカニズムがあります。 あなたが書いた言語でそれらをどのように使用するかを誰かに教えてもらってください。 メソッドの最初に前提条件のステートメントを記述し、メソッドが終了する行の前に事後条件のステートメントを記述します。 (もちろん、これは各メソッドに正確に1つのリターンポイントがある場合に最も簡単に実行できます。)プログラムを実行し、一部のステートメントが正しくないことが判明した場合、問題が何であるかがわかり、デバッグが容易になります。



その後、各メソッドのテストまたは例作成して、正しく機能することを確認します。 自信が持てるようになるまで、残りの部分とは別に各部分をテストします。 多くの簡単なテストを使用します。 メソッドがリストを並べ替える場合は、空のリスト、1、2、3つの同一の要素のリスト、逆の順序の3つの要素、いくつかの長いリストを試してください。 ほとんどの場合、バグは簡単なテストで表示され、分析が容易になります。



最後に、プログラムにまだバグがある場合は、例を開始するときにコードの各行から予想されるアクションの正確な説明を紙に書きます 。 プログラムには20行しかかかりません。 あなたは彼女がするすべてを書くことができるはずです。 次に、デバッガを使用してコード調べ、各ステップで各変数をチェックし、紙でプログラムの動作を1行ずつチェックします。 プログラムが紙に書かれていないことをする場合、エラーは紙にある(この場合はプログラムの動作がわからない)か、プログラムにある(この場合は何か間違ったことを書いた)。 間違っているものを修正してください。 修正方法がわからない場合は、少なくともStackOverflowで特定の技術的な質問をすることができます! いずれにしても、プログラムの動作の説明とプログラムの実際の動作が一致するまで、プロセスを繰り返します。



あなたがデバッガで作業している間、私はあなたにわずかな疑いに注意を払うことをお勧めします。 ほとんどのプログラマーは当然、自分のコードが期待どおりに機能すると信じていますが、そうではないので、あなたはそれをデバッグしています! 多くの場合、コードをデバッグしましたが、私の目の隅からVisual Studioのちらつきに気づきました。これは「このメモリが変更されたところです」という意味で、このメモリが私の問題にまったく適用されないことがわかりました。 それで、なぜ彼女は変わったのですか? これらの不正なピッキングを無視せず、それが正しいか間違っている理由を理解するまで、奇妙な行動を研究してください。



これがすべて非常に長く、多くの努力を必要とするように思われる場合、それがそうであるという理由だけで。 自分で書いた20行のプログラムでこれらの手法を使用できない場合、他の誰かが書いた200万行のプログラムでそれらを使用できるとは考えられません。 ただし、業界の開発者はこれを毎日行います。 トレーニングを始めましょう!



そして次に宿題を解決するときは、メソッド自体を記述する前に、各メソッドの仕様、例、テスト、前提条件、事後条件、およびステートメントを記述してください ! バグが発生する可能性を大幅に削減できます。バグが発生した場合は、ほとんどの場合すぐに見つけることができます。



この手法は、各プログラムのすべてのバグを見つけるのに役立ちませんが、初心者プログラマーが宿題で書く短いプログラムには非常に効果的です。 また、重要なプログラムのバグを見つけるためにも使用できます。



All Articles