突然ですが、プログラムは一連の処理をまとめた「関数」と呼ばれるブロック単位で処理を行います。数学で使う関数とイメージ的には同じですね。
プログラムはメインとなる関数の中で、処理の開始から終了に至るまでの一連の流れを記述します。すごく単純な処理、例えば足し算や引き算を行うだけならば、一つの関数の中で完結しますが、そうでない場合はメインの関数の中で、様々な関数を呼び出して複雑な処理を構成していきます。
これを「関数の呼び出し」と表現したりしますが、今回は関数を呼び出す際に、その関数に引数を渡す方法の「値渡し」と「参照渡し」に関して解説します!
関数の呼び出しと引数
関数を呼び出す際には呼び出し元から必要なデータを受け取ることができますが、このデータのことを「引数」と呼びます。
例えば、「A + B」を行う関数「add()」という関数があった場合に、この関数に「A」と「B」のデータを渡す必要があります。
そのために呼び出し元で最初に「A=2」、「B=3」といった値を変数に入れて、呼び出し関数にその値を引数として渡します。
この時に、呼び出し元が渡す引数のことを「実引数」、呼び出された関数側が受け取る引数を「仮引数」と呼びます。ちょっとややこしいので、図で解説してみます。
呼び出し元の関数に実引数で「A=2, B=3」を入れて、呼び出された関数側でそれを「X=2, Y=3」として扱って、結果の「Z=5」を返してメインの関数内で「Z=C=5」となるのですね。
そして、この関数への引数の渡し方には「値渡し」と「参照渡し」の二つの方法があり、上記の例で出てきたそれぞれの変数「A,B,X,Y」の値が渡し方によって変化しますので、そこのポイントを次から解説していきます。
値渡しとは?
値渡しは一言で言うと「引数をコピーして渡す」となります。
「呼び出し元の関数」で定義した実引数の値を「呼び出された関数」の仮引数にコピーして渡すので、呼び出された関数内で、仮引数の値が変わっても、実引数側の変数は渡す前の値のままです。
例を図にしてみました。
関数に値を渡すときに「箱(元の変数)から箱(別の変数)」に値を渡してあげるイメージですね。
参照渡しとは?
参照渡しは一言で言うと「引数のアドレスを渡す」となります。
値渡しと違うの点は呼び出し元にのみ実体が存在していますので、呼び出された側へは実体の場所を示す参照情報(メモリ上のアドレス)を伝えることで、計算処理などを行うことができます。
そのため、呼び出された関数側で仮引数の値が変更されると呼び出し元の変数の値が変わることがポイントです。
例を図にしてみました。
関数に値を渡すときに「箱(元の変数)のメモリのアドレス情報」を渡してあげるイメージですね。
実際の使い方
では実際の動きはどうなるか見てみましょう。
下の例ではメインの関数(呼び出し元)で値渡しの変数Aと参照渡しのBを用意し、足し算の関数(呼び出し側)へ仮引数(X, Y)として渡しています。
①呼び出し時は「X=2、Y=3」となる
②計算の結果「X=5、Y=B=8」となる
③メイン関数側は「A=2、B=8」となる
参照渡しを使うことによって、関数の呼び出し後に参照した実体の値が変わります。
プログラムの中で、それぞれどこの関数(ブロック)内に実体となる箱があり、どの箱の中身を操作しているのかが重要ですね。
まとめ
今回は関数の呼び出しの仕組みと値渡し、参照渡しに関して解説しました。
値渡しはデータを呼び出し側にコピーし、参照渡しはデータの実体が呼び出し側に存在しない、ということですね。
プログラムの言語によって渡し方はある程度決まっていますが、引数の渡し方を正しく理解しておくことは大事ですね。
プログラムの結果の値が想定と違う場合は、引数の渡し方を確認してみると良いかもしれませんね。
以上です!