新人プログラマ応援記事のつもりで書いたらそんなものではなくなってしまった……
TL;DR
「参照型」
……データの取扱方式のひとつ。
「参照渡し」
……該当の関数へ処理対象を報せる方式のひとつ。
同じ「参照」だが意味は全く違う。参照型を渡すから参照渡しではない。
参照型 is 何
↔「値型」
ざっくりいうと、
- 別の変数に代入したら全部コピーされるのが値型
- 代入しても実は同じものを見ているのが参照型
です。
あくまで一般論ですが、数値や文字列など、人間が直感的に「こりゃ値だろ」と思えるもの (なんじゃそりゃ) はなんだかんだ値型であることが多いです。
逆に複数の数値や情報を扱うものはたいてい参照型です (例外はままあるけど……) 。
int i = 1; // 整数はたいてい「値型」
int[] i = [1,2,3]; // 配列はたいてい「参照型」
C/C++ を齧ったことがあるなら、「ポインタで扱わないといけないものは全部参照型」ぐらいの認識で概ね大丈夫です。
(※ ポインタ自体は値型です - メモリのアドレスを数字にしたようなもんですから)
参照渡し is 何
↔「値渡し」
関数に対してある引数 A を渡す時、
- 何らかの形で値を渡すのが値渡し (値呼び / call by value)
- A の参照を渡すのが参照渡し (参照呼び / call by reference)
です。
この時の値や参照というものは、先の「値型」「参照型」とは関係ありません。
「参照渡し」における「参照」というのは、変数の別名のようなものです。
(これらの「方式」そのものは「評価戦略」という語で呼ばれるものの一つです……ややこしくなってきたって?)
もしも「参照渡し」であった場合、引数に対して代入すると、呼び出し元のデータが差し替えられてしまいます。
(※ 渡されたものが参照型だった場合、その引数自体が自分を書き換えたり、引数の持つ変数を書き換えたりすることで呼び出し元へ影響を及ぼすことはできますが、データそのものが差し替えられるわけではありません)
// もしも参照渡しだったら……
int i = 0;
print(i); // 0
ex(i);
print(i); // 1000
void ex(int i){
i = 1000;
}
ところでなんでこんなことを?
間違った使い方をされると私が困るからです。いろんな言語使ってるので、脳内で混ざります。
例えば、Javaに参照渡しは存在しません。
(ここらへんは結構コアで、また荒れる話題です。興味があったら調べてみてください)