Code Fix

初級

配列のループが1つずれて範囲外を読む・最後の要素が抜ける

添字は0から要素数-1までという境界を1つ間違えると、最後の要素が抜けたり、配列の外を読んでしまったりします。

なぜエラーが出ないのか

出力: 170
(エラーなし)
Cは何も報告しません。コンパイルも実行も正常に完了するためです
出力: 170
実際の挙動 — 期待した結果と食い違っている箇所
見つけ方
エラーが出ないので、出力を目で確かめるか、コードを目で追うしかありません。この種の誤りが最も発見が遅れます

このエラーが出る典型パターン

パターン1

 1  #include <stdio.h>
 2  
 3  int main(void) {
 4      int scores[3] = {70, 80, 90};
 5      int sum = 0;
 6      for (int i = 1; i < 3; i++) {
                     ^
 7          sum += scores[i];
 8      }
 9      printf("%d\n", sum);
10      return 0;
11  }
出力: 170期待: 240

ループをi=1から始めると、添字0の要素(70)が合計に含まれません。配列の最初の要素は添字0であることを忘れると起きるミスです。

直し方: 10 にします。

この問題を解いてみる →

広告
広告スロット(未設定)

パターン2

 1  #include <stdio.h>
 2  
 3  int main(void) {
 4      int prices[4] = {10, 20, 30, 40};
 5      int total = 0;
 6      for (int i = 0; i < 3; i++) {
                            ^
 7          total += prices[i];
 8      }
 9      printf("%d\n", total);
10      return 0;
11  }
出力: 60期待: 100

要素数4の配列なのに境界をi<3にすると、最後の要素(40)が合計に含まれません。有効な添字は0〜3までなので、境界には要素数そのものを使います。

直し方: 34 にします。

この問題を解いてみる →

パターン3

 1  #include <stdio.h>
 2  
 3  int main(void) {
 4      int temps[5] = {18, 20, 19, 21, 17};
 5      int count = 4;
                    ^
 6      int sum = 0;
 7      for (int i = 0; i < count; i++) {
 8          sum += temps[i];
 9      }
10      printf("%d\n", sum);
11      return 0;
12  }
出力: 78期待: 95

countを要素数5より1つ少ない4にすると、最後の要素(17)が合計から漏れます。要素数を数える変数は実際の要素数と一致させる必要があります。

直し方: 45 にします。

この問題を解いてみる →

よくある誤解

「要素数と同じ数まで回せば全部読める」という直感はCでは通用しません。要素数5の配列で有効な添字は0〜4で、<=を使うと存在しない5番目にアクセスしてしまいます。範囲外アクセスはエラーにならず、たまたま近くにあった値を読んでしまうため発見が遅れます。

まとめ

配列のループが1つずれて範囲外を読む・最後の要素が抜けるは初級でつまずきやすい項目です。上の3パターンを実際に手で直すと、エラーメッセージのどこを読めばよいかが掴めます。

演習をはじめる

関連するエラー

広告
広告スロット(未設定)