はじめに
関数への引数の渡し方には「値渡し」と「参照渡し」があります。
例えば、次のような「関数A」があるとします。「関数A」には「引数」があり、「関数A」を呼び出すときは引数を指定します。
この関数への引数の渡し方には「値渡し」と「参照渡し」があります。
本記事では「値渡し」と「参照渡し」の違い、そして「参照の値渡し」について解説しています。
値渡しとは
値渡し(英:call by value)とは、変数の値(実体)をコピーして渡す方法です。変数の実体はメモリ上で管理されています。
スポンサーリンク
このメモリ上で管理されている「変数」を"値渡し"で「関数」に渡すと、どうなるのでしょうか。以下は"値渡し"のイメージ例です。
「変数A」を"値渡し"で「関数A」に渡すと、「変数A」の値(実体)をコピーして「関数A」に渡します。実体をコピーしているので、メモリ上の値もコピーします。
結果、呼び出し元の「変数A」と呼び出された関数の「引数A」は異なる実体を参照しています。
そのため、関数内で「引数A」の値を変更しても、呼び出し元の「変数A」に影響を及ぼすことはありません。
参照渡しとは
参照渡し(英:call by reference)とは、変数のメモリの番地を渡す方法です。
「変数」を"値渡し"で「関数」に渡す場合は、「変数」の値(実体)をコピーして「関数」に渡していましたが、"参照渡し"で「関数」に渡す場合は、「変数」のメモリ番地(メモリ上の位置)を「関数」に渡します。(メモリ上は実体のメモリ番地がコピーされ「関数」の引数はコピーされたメモリ番地を参照する)
以下は"参照渡し"のイメージ例です。
"参照渡し"で値を関数に渡す場合は、実体のメモリ番地(メモリ上の位置)を渡すため、呼び出し元の「変数A」と呼び出された関数の「引数A」は同じ実体を参照しています。
そのため、関数内で「引数A」の値を変更すると、呼び出し元の「変数A」の値も変わります。
参照の値渡し
Javaなどの多くのプログラミング言語は、"参照の値渡し"により参照渡しに相当する機能を実現しています。
例えば、Javaではオブジェクトへの参照を参照型の値として管理しています。
参照型のイメージは次のとおりです。オブジェクトの実体とは別にメモリ番地(メモリ上の位置)が作られ、そのメモリ番地を参照している形です。
この参照型の値を"値渡し"で「関数」に渡すと、次のように実体のメモリ番地をコピー(メモリ番地を"値渡し"で渡している)します。
結果、「呼び出し元変数」と「関数の引数」は同じ実体を参照しています。
"値渡し"で値(メモリ番地)を渡しているが、"参照渡し"に相当する機能を実現、これが"参照の値渡し"です。
まとめ
- 値渡し:変数の値(実体)をコピーして渡す方法
- 参照渡し:変数(実体)のメモリ番地を渡す方法
- 参照の値渡し:値渡しで変数のメモリ番地を渡す方法