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

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

新規登録して質問してみよう
ただいま回答率
85.50%
Java

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

Q&A

解決済

6回答

1580閲覧

配列変数の理解に苦しんでます。

prog1717nm

総合スコア56

Java

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

0グッド

0クリップ

投稿2016/07/24 11:00

public class Swap { public static void main(String[] args) { int[] a={10, 20}; int[] b={10, 20}; swap(a); System.out.printf("%3d%3d\n", a[0], a[1]); swapVal(b[0], b[1]); System.out.printf("%3d%3d\n", b[0], b[1]); } static void swap(int[] a) { int x=a[0]; a[0]=a[1]; a[1]=x; } static void swapVal(int x, int y) { int w=x; x=y; y=w; } } ``` 上のプログラムの実行結果は 20 10 10 20 なのですが、なぜ配列aだけしか逆にならないんでしょうか? 配列bも『int w=x; x=y; y=w;』の部分で10と20の値が入れかわり、逆になると思うのですが。教えて下さい。

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

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

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

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答6

0

ベストアンサー

変数宣言において、newを用いて宣言するものはすべてオブジェクト型変数です。
オブジェクト型→参照渡し(正確には違うけど)
プリミティブ型→値渡し
となっています。

int[] a={10, 20};
これにはnewがないじゃないか!となると思いますが、これはコンパイル時に
int[] a = new int[]{20, 10};
という形に直しています。これにはnewがあります。

値を代入しない配列の宣言も
int[] a = new int[3];
みたいにnewがありますし。

この場合は、aはnewを代入したオブジェクト型変数
a[0]とa[1]はそれぞれ20と10という値を代入したプリミティブ型変数(のようなもの)です。
これはbでも同じです。

参照渡しは、渡した先と値を共有する。
値渡しは、渡した先と値を共有しません。

だから今回のような結果になります。

投稿2016/07/25 01:31

intelf___

総合スコア868

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

既に詳しい説明があるので詳細は省きますが、値渡しと参照渡しは理解し辛いですよね。
簡単に覚えるために以下に回答をしておきます。

Javaは型の種類として大きく2つあります。

1.具体的な整数値や実数値を格納するためのプリミティブ型
2.クラスインスタンスや、プリミティブ型を配列にした、参照型

プリミティブ型は以下のとおり

byte short int long char float double boolean

以下はプリミティブ型のラッパークラス(一部名称が違いますが、頭が大文字です)

Byte Short Integer Long Character Float Double Boolean

他にも先に説明した、プリミティブ型の配列は全て参照型、
それ以外のクラスも全て参照型となります。

プリミティブ型は値渡しなので、呼び出し先の関数内で値を変更しても、呼び出し元では不変。
参照型は参照渡しなので、呼び出し先の関数内で中身の値を変更したら、呼び出し元でも変更される。

いかがでしょうか。

投稿2016/07/24 15:35

moonphase

総合スコア6621

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

既に素敵な回答が他の方から出てますので蛇足で。

配列変数以外にも、
意識しないといけない点があるので順番に説明します。
先ずそれぞれのメソッドがやっている事を確認しましょう。

  • Swapメソッドについて

Java

1 static void swap(int[] a) { 2 int x=a[0]; a[0]=a[1]; a[1]=x; 3 }

上記がやっている事ですが、
引数で受け取った配列の各要素の数値を入れ替えた上で配列に設定し直しています。
これは質問者さんの想定通りですので特に問題ないですね。

  • SwapValメソッドについて

Java

1 static void swapVal(int x, int y) { 2 int w=x; x=y; y=w; 3 }

上記は呼び出し元から値をコピーして受け取った数値を、当該メソッドのローカル変数で入れ替えています。

つまりやってることが全然違っていたりします。

ついでなので上記に出てきた値渡し、ローカル変数についても説明します。

###値をコピーして受け取るとは
int型やdouble型などの基本データ型を引数として受け取るとこの挙動となります。
今回のケースだとswapValメソッドには配列bの各要素の数値がコピーされた状態となり、この時点で元々のb配列との関連は一切なくなっています。
これは**値渡し(call by value)**とも呼ばれます。

また値渡しと関連するもので**参照渡し(call by reference)**というものも存在します。
厳密には違うものですがswapメソッドの方がちょうどそれに近い振る舞いをします(配列は参照型データ)。
この辺りは最初につまづきやすい所なので以下のリンクなどで目を通してしておくと良いでしょう。
【Java初心者】値渡しと参照渡し

###ローカル変数とは
ローカル変数とは宣言されたブロックでのみ有効となる変数の事です。
上記のコードだとswapValメソッド内で宣言されたint型の変数たちは、
このメソッド内でしか有効となりません。
もう一つ例を挙げると、

Java

1if (条件) { 2 int i = 10; 3} 4// i = 0; ifブロック内で宣言されているためそもそもコンパイルエラー

上記の変数iはifブロック内でのみしか有効となりません。
こういう有効範囲の事を変数のスコープとか言ったりします。

ローカル変数と対になる用語としてグローバル変数というのもあります。
興味あったら調べてみると良いと思います。

・最後に
色々覚える事も多くて大変かと思いますが、
一つずつ確実に吸収していく事がプログラミング向上の近道です。
頑張ってくださいね^^

投稿2016/07/24 12:03

編集2016/07/24 12:14
Panzer_vor

総合スコア1636

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

メソッドの引数にはその値のコピーが渡されるだけです。swapValにbの配列要素を渡したところでは、メソッド内の変数が「xが10、yが20」という情報があるだけで、それが「配列bの要素だ」ということは一切なくなります。このxとyの値を入れ替えようが、配列bからは関係のない話なので、配列bの要素に変化はありません。

投稿2016/07/24 12:01

swordone

総合スコア20649

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

javaの関数呼び出し時の引数は値をコピーしているだけです。

従って、bについてはコピーされたもの同士を入れ替えているのでオリジナルに影響はありません。一方、aについては配列を渡しています。配列を辿って、この中身を変更しているのでオリジナルの中身にも影響が出ます。

投稿2016/07/24 11:55

HogeAnimalLover

総合スコア4830

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

配列bも『int w=x; x=y; y=w;』の部分で10と20の値が入れかわり、逆になると思うのですが。教えて下さい。

配列bじゃなくて、swapValメソッドの中のローカル変数が書き換わっているだけです。
仮引数がint x, int yなので、実引数のb[0]b[1]の「値」がメソッドに渡ります。
つまり、下記と同じです。

Java

1int x = b[0]; 2int y = b[1]; 3int w=x; x=y; y=w; 4System.out.printf("%3d%3d\n", b[0], b[1]);

投稿2016/07/24 11:11

otn

総合スコア84421

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.50%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問