x = 10
という変数xについて考える。
ここで、
x
と書いた場合、xの値が返ってくる。
&x
と書いた場合、xの参照(参照値)が返ってくる。参照とはメモリ上のアドレスのことである。
次に、なんかの関数func()があるとする。以下のようにして呼んでみる。
func(x)
これが、値渡しである。
func(&x)
これが、参照渡しである。
さて次に、新しく変数yについて考える。
y = &x
yはxの参照を値として持っている。
これもx同様、
y
と書くとyの値が返ってくる。
&y
と書くとyの参照が返ってくる。
で、ここから本題。以下のように関数func()を呼んでみる。
func(y)
再度書くが、yはxの参照を 値 として持っている。
・「yの値を渡してるんだから『値渡し』と呼ぶよ(でもまあ、xの参照を渡してるからあえて言うと『参照の値渡し』だよ)」派
・「xの参照を渡してるんだから『参照渡し』と呼ぶよ」派
のバトルである。
歴史的に(?)は前者が正しいのだが、後者の誤解は根深く今も争いの種となっている。
ちなみにこの話にC言語とC++が入ってくるとややこしくなる。なぜなら「C言語には参照渡しはない」からである。別の表現をすれば、「他言語で『参照渡し』と呼んでいるものの書き方と、C言語で『ポインタ渡し』と呼んでいるものの書き方は非常によく似ている」である。
C言語だけ呼び名が違うので、C言語は他言語と違う言葉を使いだした空気読めてない糞言語みたいに見えるが、おそらく順序としては逆である。
(1) C言語では「値渡し」と「ポインタ渡し」が使われてきた
(2) ポインタを直接扱うのはバグの温床だよね、ということに人類が気づき始める
(3) C言語の進化版C++では新しく「参照渡し」という機能が追加された。これは「ポインタ渡し」に代わる「制約の厳しいポインタ渡し」みたいなものであった
(4) モダンな言語ではポインタという概念を捨て(?)、この「参照渡し」を参考にした(ただしモダンな言語の『参照』とC++の『参照』は意味合いが異なる)
(5) モダンな言語では「値渡し」と「参照渡し」の2種類がスタンダードとなった
構文的にはモダンな言語の「参照渡し」とC言語の「ポインタ渡し」は似た書き方をするので、モダンな言語学習者がC言語の「ポインタ渡し」を見て「C言語では参照渡しってこう書くのかー^^」と言うとフルボッコにあい、C++の「参照渡し」を見て「C++の参照渡しってこう書くのかー^^」と言った場合でもその理解はずれている場合が多い。