初心者のJavaプログラミング

プログラミングガチ初心者がIT業界を目指して頑張ります。

【第5回】初心者のJavaプログラミング【配列】

こんにちは。
昨日はちょっと疲れていまして、書けませんでした。
今日は頑張って書こうと思います。
テーマは「配列」です。

配列の基本

1.まずは変数の宣言

// 宣言。int型のarrayという配列名の変数を作成。
int array[];

変数の宣言は、今まで習ってきた変数と同じように宣言します。
違うところは変数名の後ろに、「 [] 」を付けるところです。
これが、配列を表す記号です。また、この段階ではまだメモリ上に配列の領域が割り当てられていません。

2.配列に領域を割り当てる

// 実際にint型5個分の領域を割当。
array = new int[5];

次にするのが、配列に領域を割り当てることです。
newというものを使っていますが、何なのかはまだ分かりませんw
新しく作っちゃうよー的な意味なのでしょうか。
このように「 [] 」の中に数字を入れることによって、配列の大きさ(長さといった方がわかりやすいかもしれません)が決まります。

1と2をいっぺんにやる方法もあります。

int array[] = new int[5];

3.配列の各要素を初期化

// 各要素を初期化
array[0] = 12;
array[1] = 34;
array[2] = 56;
array[3] = 28;
array[4] = 61;

配列の各要素に値を代入しています。
配列の一番最初のIndex番号は0番なので気をつけましょう!
配列の一番最後のIndex番号にも気をつけましょう。要素数 - 1 番です。0番から始まっているからですね。


これが配列の宣言、領域の割り当て、初期化のプロセスです。
この一連の流れを、サクッとやってしまう方法があります。配列初期化子を利用します。

int array[] = { 12, 34, 56, 28, 61 };

こちらの方が分かりやすいですね!

配列変数に別の配列変数を代入

何が表示されるでしょうか!

class Test {
	public static void main( String args[] ) {
		int array_1[] = new int[2];
		int array_2[] = new int[2];
		// array_1を初期化
		array_1[0] = 5;
		array_1[1] = 10;

		// array_2を初期化
		array_2[0] = 20;
		array_2[1] = 30;

		// array_2にarray_1を代入。ここが重要
		array_2 = array_1;

		// array_2[1]に50を代入。
		array_2[1] = 50;

		System.out.println(array_1[1]);
	}
}

答えは50です。30じゃないです。
これは図を使って説明します!じゃん!
f:id:fightingneetkun:20140715174822p:plain
外枠の四角がメモリです。

  1. 実は配列の宣言をすると図の青のとこにメモリが確保されます。この段階ではどのくらいの大きさの配列を用意するのか決まっていません。
  2. 次に領域の割り当てをすると実際に配列変数とは別のところにメモリの領域が確保されます。この場合はint型2つの配列なので、32ビット + 32ビット分の領域が割り当てられることになります。(図の黄色の部分)

なので配列変数には実際に値は入っていないのです。実体は別なところにあります。その別なところにある実体を指し示しているだけです。(これを参照といいます)
では配列変数には何が入っているのかというと、実体がある場所(アドレス)が入っています。この場合は、配列の先頭のアドレスが格納されています。
配列変数array_1が参照元、実体(この場合は2要素)が参照先で、参照元から参照先の値を見に行くことを参照と言います。

元々array_1とarray_2は別々の領域を参照していましたが、
f:id:fightingneetkun:20140715181548p:plain

array_2 = array_1;

上記の代入によって、array_1が参照していた領域をarray_2も参照することになります。
f:id:fightingneetkun:20140715180917p:plain
よって、実体の実際の値を変更すると、array_1にもarray_2にも影響が出ることになります。同じところを見ているからです。

めっちゃむずいっすねw
私も今日習ったことなので、本当にこの理解でいいのか少し不安です。厳密に言うと違うのかもしれません。
詳しい方いらっしゃいましたら、間違ってるよーとコメントいただければ幸いです。


今日はこれでおわりです。<追記>2014/07/17
勘違いしてました。
int array[];
コンパイラに対しての宣言なので、メモリは確保されません。
なので図の青い部分は間違っています。でも参照のイメージは何となくつかめそうだと思ったので、一応残しておきます。もっとわかりやすそうな表現があったら、適宜変えていきます。