配列の要素にアクセス
3 番目の点数は scores[3] ではない
配列から値を取り出すときは、名前の後ろに [] を書いて、その中に 番号 を入れます。この番号を添字、またはインデックスと呼びます。
厄介なのは、その番号が 0 から始まることです。
Java
int[] scores = {80, 65, 92};
System.out.println(scores[0]); // 80
System.out.println(scores[1]); // 65
System.out.println(scores[2]); // 92日常の数え方だと 92 は 3 番目ですが、配列では scores[2] です。番号は「何番目か」ではなく「先頭から何個ぶん離れているか」だと思うと腑に落ちます。先頭は 0 個ぶんしか離れていないので 0、その次は 1 個ぶんで 1 です。
取り出すだけでなく、書き換えるのも同じ形です。scores[1] = 70; と書けば、2 つ目の値が 70 に変わります。
末尾は arr.length - 1
長さ 3 の配列で使える番号は 0 1 2 の 3 つです。個数は 3 なのに、最後の番号は 2 になります。
| 書き方 | 長さ 3 の配列で指すもの |
|---|---|
scores[0] | 先頭 |
scores[scores.length - 1] | 末尾 |
scores[scores.length] | どこも指さない |
末尾を取りたいときは scores.length から 1 を引きます。長さがいくつでもこの形なら通用するので、末尾を触るコードでは決まり文句として出てきます。
Java
int[] scores = {80, 65, 92};
int last = scores[scores.length - 1]; // 92範囲の外を読むと、その場で落ちる
存在しない番号を指すと、Java はプログラムをその場で止めます。
Java
int[] scores = {80, 65, 92};
System.out.println(scores[3]); // ArrayIndexOutOfBoundsExceptionエラーには Index 3 out of bounds for length 3 のように、指した番号と配列の長さが並んで出ます。長さ 3 の配列に対して 3 番を読もうとした、という意味です。負の番号も同じで、Python のように scores[-1] で末尾が取れる仕組みは Java にはありません。
つまり安全に読める番号は、0 以上で、かつ長さより小さいものだけです。外から番号を受け取るメソッドでは、読みに行く前にこの範囲に収まっているかを自分で確かめる必要があります。渡された番号を信じて読むと、想定外の値が来た瞬間にプログラムごと止まります。
落ちるのは不便に見えて、実は親切な設計です。
C言語では範囲外を読んでも止まらず、無関係なメモリの中身が返ってきて、原因の分からないバグになります。
やってみよう
今回は、配列と番号を受け取って、その位置の値を返すメソッドを書きます。範囲の外を指されたときは例外を起こさず、決められた値を返して切り抜けます。
条件を書く前に、境界を数直線で確かめてください。長さ 3 なら 2 は内側で 3 は外側、0 は内側で -1 は外側です。ここをはっきりさせてから書けば、< と <= のどちらを使うかで迷いません。
要件
- メソッド名は
getAt、引数はint[] arrとint indexの 2 つ、戻り値の型はintにすること indexが0以上かつarr.length未満のとき、arr[index]を返すことindexが0未満、またはarr.length以上のときは-1を返すこと (ArrayIndexOutOfBoundsExceptionを発生させない)
入出力例
getAt([10,20,30], 1) → 20
getAt([10,20,30], 0) → 10
getAt([10,20,30], 5) → -1
getAt([10,20,30], -1) → -1
getAt([10,20,30], 3) → -1
getAt([], 0) → -1