こんにちは、downmeltです。
最近、生活習慣とABCの開催時間が合わず、数カ月間出れていなかったりします。
リアルタイムで出られずモチベーションは落ちてきてしまっているので、ちょっと役に立ちそうな記事を書いて気を紛らわせることにします。
実行中エラー(RE)
競プロででると腹が立つエラートップ3に入るであろう実行中エラー。
コンパイル時にエラーは出ず、代入される変数の中身によってエラーがでるパターンが多く、0や最低値、最高値などの端値などの処理がうまくいっていないとよく起こります。
テストケースだけでテストをすると見つからないこともあるので、最大値などの端値をテストする習慣をつけることも予防方法の一つですが、今回は出てしまったエラーの対応方法を書きます。
※自分で出したエラーを記憶をたどって書いているので間違いがあるかもしれません。万が一間違いがあった場合はコメントやtwitter等でご指摘いただけると幸いです。
エラー例
ゼロ除算
文字通り、0で他の値を割ることです。
分母が0以外の時は正常に動きますが、分母に0が代入されたときは割り算をすることができないためエラーが出ます。
条件分岐で計算式を使い分ける場合などに注意が必要です。
配列変数を存在しないインデックスで指定する
配列変数の要素数はn個用意した場合、インデックスは0 〜 n-1 番がふられます。
ここで、インデックスの最大値が n-1 であるということに注意が必要です。
要素数に問題のサンプルをそのまま代入すると、最大値が n でエラーが起きてしまうことがあります。
他にも起きる頻度は少ないですが 、マイナス値でもエラーは出ます 。
無限ループ
条件分岐が起きるまでループ処理を行うときに、breakの書き忘れや処理条件の書き間違いなどで、ループから抜け出せない場合はエラーが出ます。
for文での終了条件が複雑なときなどに break を使ってループを終わらせる場合や、大なりと小なりの間違えによって起きることがあるので注意が必要です。
対処方法
除算の前に条件式をつける
除算式の前に0で実行されないよう条件式をつけることで防げます。
例えばC言語の場合は、
if(a) c = b / a;
のようにif文の条件式に分母の変数を入れるなどの方法があります。
しかし、そもそも0で除算が行われるような処理が行われる場合、他の処理が間違えていることも多いので、もう一度それより上位の条件式を見直すこともお勧めします。
条件式を見直す
配列変数のエラーも無限ループも、条件式の端値が間違えているのが原因で起こることがおおいため、条件式の端値、大なり小なりの向き、=(イコール)の有無などをチェックすることで見つけられることが多いです。
特に、配列変数の要素数は、問題の値から1を引くべきかどうかをチェックしましょう。
書き直す
最終手段です。
余計時間を使いそうな方法ですが、いくら原因の箇所を探しても見つからない場合、思いもよらない単純なミスをしていることも多く、一度同じ文を書き直すだけで直ることがあります。
しかし、時間がかかることは確かなので、間違っている箇所はないという先入観に脳が侵されていると感じた場合の最終手段として使いましょう。
最後に
今回は出たら一番うざいという理由で実行中エラーについての対処法を書きましたが、 今後は他のエラーの対処法も書いていきたいとは思っています。
しかし、初めにも行ったようにコンテストに出れておらず、どのようなエラーがよく出るかを忘れてしまっているのでいつ出るかはわかりません。
まずはコンテストと生活習慣を合わせることから始めるので気長にお待ちください。
↓おすすめの競プロ記事
コメント