C# と VB.NET の質問掲示板

ASP.NET、C++/CLI、Java 何でもどうぞ

C# と VB.NET の入門サイト

Re[1]: メソッド引数に配列を指定した場合


(過去ログ 50 を表示中)

[トピック内 7 記事 (1 - 7 表示)]  << 0 >>

■27473 / inTopicNo.1)  メソッド引数に配列を指定した場合
  
□投稿者/ じゅん (1回)-(2008/11/07(Fri) 10:36:31)

分類:[Java] 

2008/11/07(Fri) 11:56:47 編集(投稿者)

Windows XP
Java 1.5

お世話になります。

以下のコードを実行し、
出力された結果がなぜそうなるのか理解できず、
質問させて頂きます。

10行目で、引数xに、y配列への参照を代入していますので、
6行目で出力される結果は、11行目で出力される結果と
同じであると思っていました。

よろしくお願いします。


1:class Test1107_0021{
2: public static void main(String args[]){
3: int x[] = {11,12,13,14,15};
4: display(x);
5: change(x);
6: display(x);
7: }
8: public static void change(int x[]){
9: int y[] = {21,22,23,24,25};
10: x = y;
11: display(x);
12: }
13: public static void display(int x[]){
14: for (int i=0; i<x.length; i++){
15: System.out.print(x[i] + " ");
16: }
17: System.out.println();
18: }
19:}

(出力結果)
11 12 13 14 15 ← 4行目の実行で出力される
21 22 23 24 25 ← 11行目の実行で出力される
11 12 13 14 15 ← 6行目の実行で出力される

引用返信 編集キー/
■27477 / inTopicNo.2)  Re[1]: メソッド引数に配列を指定した場合
□投稿者/ aetos(旧シャノン) (23回)-(2008/11/07(Fri) 11:15:12)
No27473 (じゅん さん) に返信
> 10行目で、引数xに、y配列への参照を代入していますので、
> 6行目で出力される結果は、11行目で出力される結果と
> 同じであると思っていました。

10 行目の理解を間違えています。
「x 自体を変更する」のと「x の中身を変更する」の違いです。
引用返信 編集キー/
■27482 / inTopicNo.3)  Re[2]: メソッド引数に配列を指定した場合
□投稿者/ じゅん (2回)-(2008/11/07(Fri) 12:11:36)
返信ありがとうございます。

No27477 (aetos(旧シャノン) さん) に返信
> ■No27473 (じゅん さん) に返信
>>10行目で、引数xに、y配列への参照を代入していますので、
>> 6行目で出力される結果は、11行目で出力される結果と
>>同じであると思っていました。
>
> 10 行目の理解を間違えています。
> 「x 自体を変更する」のと「x の中身を変更する」の違いです。

せっかく、ご教授頂いたのですが、
JAVAを始めて二週間の私には違いが理解できません。
大変申し訳なく思いますが、もう少し教えていただけないでしょうか。

引用返信 編集キー/
■27486 / inTopicNo.4)  Re[3]: メソッド引数に配列を指定した場合
□投稿者/ aetos(旧シャノン) (24回)-(2008/11/07(Fri) 13:19:24)
No27482 (じゅん さん) に返信
> せっかく、ご教授頂いたのですが、
> JAVAを始めて二週間の私には違いが理解できません。
> 大変申し訳なく思いますが、もう少し教えていただけないでしょうか。

例えば、

public static void NoChange( int x )
{
 x = 2;
}

public static void Sample()
{
 int a = 1;
 NoChange( a );
}

というコードを書いた時、Sample の中の a が 2 にならないということはわかりますね。
これと同じことです。

これが何故 2 にならないかというと、参照渡しではなく値渡しだからですね。
値渡しということはコピーが渡されるということであり、それはつまり、NoChange が呼ばれた直後(2 を代入する前)の x と a は同じ内容を持っているけれど、別の変数であるということです。

ここまではいいですね。

ところで、「参照渡し」というのは「参照の値渡し」と言い換えることができます。
参照とは、データの場所を示すデータのことですね(想像しやすければ、「メモリ上の番地を表す値」と考えてもいいです)。
(参照の)値渡しですから、change は、main の中の x の場所を示すデータ「のコピー」を受け取るのです。
change が呼ばれた直後(y を代入する前)の x と main の中の x は同じ内容を持ってはいるけれど、別の変数だということです。
ですから、change の中で x 自体に y を代入しても、それはコピーを書き換えているだけで、main には影響を与えないのです。
これは先に示した NoChange と同じことです。

というような感じでいかがでしょうか。
引用返信 編集キー/
■27487 / inTopicNo.5)  Re[4]: メソッド引数に配列を指定した場合
□投稿者/ 初心者 (189回)-(2008/11/07(Fri) 13:33:45)
class Tekito{
	public static void main(String args[]){
		int x[] = {11,12,13,14,15};
		display(x);
		change(x);
		display(x);
	}
	public static void change(int x[]){
		int y[] = {21,22,23,24,25};
		for ( int i = 0 ; i < x.length ; i ++){
			x[i] = y[i];
		}
		//x = y;
		display(x);
	}
	public static void display(int x[]){
		for (int i=0; i<x.length; i++){
			System.out.print(x[i] + " ");
		}
		System.out.println();
	}
}

実行して、元のソースとどこがどう違うのか比べてみればわかるかも。

引用返信 編集キー/
■27488 / inTopicNo.6)  Re[5]: メソッド引数に配列を指定した場合
□投稿者/ ごんごん (1回)-(2008/11/07(Fri) 13:47:33)
自分が理解しやすかったと思える文章を載せてみますね。
自分の文章ではなく、コピペです。

参照渡しと値渡しの違いと、どのような時に参照渡しになり
どのような時に値渡しとなるのかがわかりやすいかと思います。


■例
メソッド:自動販売機で商品を買う
引数:お金
返り値:商品
自動販売機という処理装置に
お金を引数として与えると
返り値に商品が出てきます。

■引数の参照渡し(オブジェクト)
引数として渡した場合、渡したモノを参照元と参照先で共有します。
メソッドに引数として財布を渡した場合、
メソッドの呼び出し先で、財布の中のお金を使うと
当然メソッドの呼び出し元でも、財布の中のお金は減っています。

■引数の値渡し(intなどのプリミティブ型)
引数として渡した場合、渡した値のコピーがメソッドに渡ります。
メソッドに引数として1000円を渡した場合、
メソッドの呼び出し先で800円使えば、呼び出し先では残金200円です。
しかしメソッドの呼び出し元では、残金は1000円のままです。


オブジェクトというのはこの場合、財布そのものです。
プリミティブ型というのはこの場合、お金そのものです。
引数に与えられるモノの型によって渡し方が変わるところが
Javaをはじめたばかりの人は理解できないかもしれません。
が、はじめはそういうものだ、と覚えておいて
あとで自分で理解できるようにしていけば良いかと思います。

あくまでもこれは自分の考えですが、自分はこれで挫折せずに進んでこれました(笑)
引用返信 編集キー/
■27494 / inTopicNo.7)  Re[1]: メソッド引数に配列を指定した場合
□投稿者/ じゅん (4回)-(2008/11/07(Fri) 15:39:13)
皆様ありがとうございます。

>(参照の)値渡しですから、change は、main の中の x の場所を示すデータ「のコピー」を受け取るのです。
>change が呼ばれた直後(y を代入する前)の x と main の中の x は同じ内容を持ってはいるけれど、別の変数だということです。
>ですから、change の中で x 自体に y を代入しても、それはコピーを書き換えているだけで、main には影響を与えないのです。

10:x = y;
この場合は、理解できたのですが、

10: for ( int i = 0 ; i < x.length ; i ++){
x[i] = y[i];
}
となった途端、main側が更新されてしまい、また解らなくなってきました。

x = y の場合、
yには、値が格納されている場所を示すアドレスが格納されているため、
コピーされた変数xへ代入しても影響なし。

x[i] = y[i] の場合、
[i]を付加することで、実際の値が格納されているアドレスを示していることとなり、
main側の更新が行われる。


上記のような認識でよろしいでしょうか?


引用返信 編集キー/


トピック内ページ移動 / << 0 >>

このトピックに書きこむ

過去ログには書き込み不可

管理者用

- Child Tree -