質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

90.47%

  • Java

    14104questions

    Javaは、1995年にサン・マイクロシステムズが開発したプログラミング言語です。表記法はC言語に似ていますが、既存のプログラミング言語の短所を踏まえていちから設計されており、最初からオブジェクト指向性を備えてデザインされています。セキュリティ面が強力であることや、ネットワーク環境での利用に向いていることが特徴です。Javaで作られたソフトウェアは基本的にいかなるプラットフォームでも作動します。

  • 多次元配列

    36questions

    1次元配列内にさらに配列を格納している配列を、多次元配列と呼びます。

java多次元配列の実行結果を解説いただけませんでしょうか

解決済

回答 4

投稿

  • 評価
  • クリップ 0
  • VIEW 913

BSS_sapporo

score 32

javaの勉強をしています。
以下のコードで、arr[i]が3となり、
16行目「str += arr[i];」でエラーとなるという事が理解ができません。
解説をお願いできませんでしょうか。
よろしくお願いいたします。

public class Array {

    public static void main(String[] args){
        int[][] array = new int[4][];
        array[0] = new int[3];
        array[1] = new int[5];
        array[2] = new int[2];
        array[3] = new int[4];

        for(int[] arr : array) {
            String str = new String();

            for(int i = 0;i < arr.length; i++) {
                 if(i == 0) {
                      arr[i] = ++i;
                 } else {
                     arr[i] = i++;
                 }
                 str += arr[i];
            }
            System.out.print(str);
         }
     }
}

  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 4

checkベストアンサー

0

i++++iは、i自体の値が書き換わります。
そのため、例えばarray[0]の長さ3のint配列arrに対し、for文中i=2で入ったとすると、
arr[2]に2が代入され、iは1増えて3になります。
結果、elseを抜けたあとのstr += arr[i];arr[3]にアクセスしようとします。
しかしarrは長さ3で、インデックス3はないため例外となります。


最初からfor文の動きを追うと…
arrayから最初の配列array[0]をarrとして扱い、ループ開始
新たな空のStringを生成
i=0でループ開始、arr.lengthは3より小さいのでループに入る
i=0なのでarr[i] = ++i;を実行、arr[0]に、iを1増やし(i=1になる)その結果が代入される。
str += arr[i];i=1なので、strにarr[1]、つまりデフォルトの0が文字列化され追加される
i++でiは1増加し2になる。arr.lengthの3より小さいのでループ続行
iが0でないのでarr[i] = i++;が実行。arr[2]にi(=2)を代入し、iを1増やす(i=3になる)。
str += arr[i];i=3のためarr[3]にアクセスしようとするが、長さ3の配列にインデックス3は存在しないため、ArrayIndexOutOfBoundsException発生。

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2016/04/06 11:17

    知識が無くて申し訳ございません、
    arrの長さはなぜ、3になるのでしょうか。

    キャンセル

  • 2016/04/06 11:19

    ご自分でarray[0] = new int[3]; と初期化してますよね?
    最初のfor文 for(int[] arr : array) で、最初にアクセスされるのがこの長さ3の配列になります。

    キャンセル

  • 2016/04/06 11:30

    array[0] = new int[3]にアクセスしに行くということなのですね!

    eラーニングで学んでおり、この点についての説明がなかったので、理解できておりませんでした。
    ありがとうございます!

    キャンセル

0

ループ開始時に「i=3」だとしても、ループ内で「i++」してるので「arr[i]」のときにはi=4になってますよ。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2016/04/06 11:32

    arrの要素数は「3」なのに対し、arr[i] = i++; で「4」になってしまい、
    要素数を超えてしまっているためエラーになる、
    という解釈で間違ってないでしょうか。

    勉強不足で申し訳ございません。。

    キャンセル

  • 2016/04/06 12:15

    それであってます

    キャンセル

  • 2016/04/06 16:41

    ありがとうございます、理解することができました!

    キャンセル

0

処理結果を順に見ていくと恐らく下のようになります。
恐らく色々意図しない結果が出ているはずです。

for文に入る前の配列初期化時点でarrayの状況はこうで
[
  [0,0,0]
 ,[0,0,0,0,0]
 ,[0,0]
 ,[0,0,0,0]
]

ループ一回目
arr[i] = ++i;  // -> [[1,0,0]....] i=1 ※++iは加算してから評価
str += arr[i];  // -> str=1

ループ二回目
arr[i] = i++;  // -> [[1,1,0]....] i=2 ※i++は評価してから加算
str += arr[i];  // -> str=1 ※この時点のarr[2]は0

ループ三回目
arr[i] = i++;  // -> [[1,1,2]....] i=3
str += arr[i];  // -> error ※arr[3]は存在しないため

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2016/04/06 11:46

    arrの要素は[0][1][2]なのにループした結果、arr[3]となってしまったためエラーとなるのですね、、!
    ようやっと理解が深まりました!
    ありがとうございます!

    キャンセル

  • 2016/04/06 11:47 編集

    一つ訂正を加えるなら、intの配列は作成時に要素はすべて0で初期化されます(nullではない、と言うかintにnullはない)。
    もひとつ訂正、ループ1回目で代入する先はarr[0]です。++の処理は代入の値決定時に処理されるので、その前の代入の位置を決める際には影響しません。

    キャンセル

  • 2016/04/06 11:49

    ォォ。これはご指摘ありがとうございます。
    修正しておきます

    キャンセル

  • 2016/04/06 11:51

    intの配列はすべて0で初期化され、そこへループの結果の値が代入されていくのですね。
    ループの流れが考えている間にわからなくなってしまったりしていたので助かりました。
    ありがとうございます!

    キャンセル

0

解説は他の方が言われている通りです。
実行時エラーの内容(例外)もArrayIndexOutOfBoundsExceptionではないでしょうか。
そのままですが、配列の範囲外にアクセスしようとしたため発生しています。

配列は長さが固定長であること、もしくは、インクリメント演算子(++や--)の性質、for文の変化式の実行されるタイミングのどこかで躓かれているのだと思います。(ソースコードから読み取れます)。

とりあえず、実行時エラーが起きないように修正するには下記のようにしてください。
(ただし、意図どおりの動きかはわかりません)

public class Array {

    public static void main(String[] args){ 
        int[][] array = new int[4][]; 
        array[0] = new int[3//indexが0~2までの長さ3の配列
        array[1] = new int[5//indexが0~5までの長さ5の配列
        array[2] = new int[2//indexが0~1までの長さ2の配列
        array[3] = new int[4//indexが0~3までの長さ4の配列

        for(int[] arr : array) { 
            String str = new String();

            for(int i = 0;i < arr.length; i++) { 
                 if(i == 0) { 
                      arr[i] = i+1; 
                 } else { 
                     arr[i] = i; 
                 } 
                 str += arr[i]; 
            } 
            /*
            上のfor文は下記のように書き換えても良いです。
       が分かりづらいのでおすすめしません。
            for(int i = 0;i < arr.length; ) { 
                 if(i == 0) { 
                      /*
                       iはインクリメントされているので、
                       配列にアクセスするときには-1にしましょう。
                       普通このような書き方はしませんが。
                       */
                      arr[i-1] = ++i; 
                 } else { 
                     arr[i-1] = i++; 
                 } 
                 str += arr[i]; 
            } 
            */
            System.out.print(str); 
         } 
     } 
}

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2016/04/06 11:48

    ArrayIndexOutOfBoundsException でした!
    for(int[] arr : array) { でアクセスするのがarray[0]の中というのがポイントだったのですね。
    ありがとうございます!

    キャンセル

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 90.47%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

同じタグがついた質問を見る

  • Java

    14104questions

    Javaは、1995年にサン・マイクロシステムズが開発したプログラミング言語です。表記法はC言語に似ていますが、既存のプログラミング言語の短所を踏まえていちから設計されており、最初からオブジェクト指向性を備えてデザインされています。セキュリティ面が強力であることや、ネットワーク環境での利用に向いていることが特徴です。Javaで作られたソフトウェアは基本的にいかなるプラットフォームでも作動します。

  • 多次元配列

    36questions

    1次元配列内にさらに配列を格納している配列を、多次元配列と呼びます。