配列のループが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であることを忘れると起きるミスです。
直し方: 1 を 0 にします。
広告
広告スロット(未設定)
パターン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までなので、境界には要素数そのものを使います。
直し方: 3 を 4 にします。
パターン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)が合計から漏れます。要素数を数える変数は実際の要素数と一致させる必要があります。
直し方: 4 を 5 にします。
よくある誤解
「要素数と同じ数まで回せば全部読める」という直感はCでは通用しません。要素数5の配列で有効な添字は0〜4で、<=を使うと存在しない5番目にアクセスしてしまいます。範囲外アクセスはエラーにならず、たまたま近くにあった値を読んでしまうため発見が遅れます。
まとめ
配列のループが1つずれて範囲外を読む・最後の要素が抜けるは初級でつまずきやすい項目です。上の3パターンを実際に手で直すと、エラーメッセージのどこを読めばよいかが掴めます。