「ByVal」と「ByRef」の違い
予備知識
| 用語 | 意味 |
|---|---|
| 変数 | プログラミング言語における「値を入れておく箱」 |
| 関数 | 処理のまとまり。何かを入れると何かを計算して何かを返してくれるやつ |
| 引数(ヒキスウ) | プログラムや関数に渡す値 |
| 値渡し | 関数に変数を(引数として)渡すときの「渡し方の種類」のひとつ。渡す変数をコピーして、コピーした変数を「これを使ってね」と渡すやり方 |
| 参照渡し | 関数に変数を(引数として)渡すときの「渡し方の種類」のひとつ。変数の置いてある場所が書かれた紙を渡して「ここにある変数を使ってね」と伝えるやり方 |
それぞれの用語の意味
| 用語 | 意味 |
|---|---|
| ByVal | 「この変数(引数)は値渡しですよ!」を示す目印 |
| ByRef | 「この変数(引数)は参照渡しですよ!」を示す目印 |
似ているところ
どちらも引数の渡し方に関する用語です。

違うところ
渡し方が違います。
関数に変数を引数として渡すときの渡し方は2種類あります。
それは
1.元の変数をコピーして渡すやり方
2.元の変数の置いてある場所を書いた紙を渡すやり方
の2つです。

この2つの渡し方のうち
1.元の変数をコピーして渡すやり方
を「値渡し」と言います。

そして「この引数は値渡しですよ!」を意味する目印がByValです。

もう一方の
2.元の変数の置いてある場所を書いた紙を渡すやり方
は「参照渡し」と言います。

そして「この引数は参照渡しですよ!」を意味する目印がByRefです。

この渡し方の違いに伴い
ByVal:変数の中身を書き換えても呼び出し元には影響しない
ByRef:変数の中身を書き換えると呼び出し元の変数の中身も書き変わる
といった違いも生じます。
例えば、そうですね。
ここにピヨ太関数が ありました。

ピヨ太関数は、変数「ミカン箱」に値「ミカン1つ」を入れました。

ピヨ太関数は、値「ミカン1つ」が入った変数「ミカン箱」をピヨ子関数に引数として渡すことにしました。

ByValの場合、ピヨ太関数は変数「ミカン箱」をコピーします。

※ピヨの左手ピヨの右手(ピヨピヨフェイク)の詳細が気になる方は、用語「ピヨの左手ピヨの右手」の説明を ご覧ください。
次に、コピーした変数「ミカン箱」を「これを使ってね」とピヨ子関数に渡します。

これがByValです。
変数「ミカン箱」は2つに分身します。

おっと!大変です。
ピヨ子関数が変数「ミカン箱」の中にあるミカンを食べてしまいました。

でも大丈夫です。
ピヨ子関数に渡したのはコピーした変数「ミカン箱」です。
ピヨ太関数の手元にある変数「ミカン箱」の中身のミカンは残っています。

ByValでは
呼び出した関数内で変数の値を書き換えても、呼び出し元の変数は影響を受けない
のです。
ByRefの場合は、ピヨ太関数はピヨ子関数に「変数『ミカン箱』の置いてある場所」を書いた紙を渡します。
「変数『ミカン箱』を使いたければ、この紙を頼りに探して、見つかった変数『ミカン箱』を使ってね!」なのです。

ByValのときと違って、ByRefでは、変数「ミカン箱」は分身しません。
1つだけです。

おっと!大変です。
ピヨ子関数が「変数『ミカン箱』の置いてある場所」を書いた紙を元にして変数「ミカン箱」を見つけ、変数「ミカン箱」の中にあるミカンを食べてしまいました。

ピヨ子関数がミカンを食べた変数「ミカン箱」は、ピヨ太関数の手元にある変数「ミカン箱」と同じものです。
ピヨ太関数の手元にある変数「ミカン箱」の中にあるミカンが、なくなってしまいました。

ByRefでは
呼び出した関数内で変数の値を書き換えると、呼び出し元の変数の中身も書き変わる
のです。
これがByValとByRefの主な違いです。
他にも、メモリ領域の確保がどーたらこーたらといった違いとかもありますけどね。
一番、意識しておくべき違いは
ByVal:変数の中身を書き換えても呼び出し元には影響しない
ByRef:変数の中身を書き換えると呼び出し元の変数の中身も書き変わる
です。
個人的な使い分け
関数に対して情報を与えたいだけの場合はByValを使います。
呼び出し元から呼び出し先の関数に対する一方通行の場合です。

関数内での変更を呼び出し元にも反映したい場合はByRefを使います。
呼び出し元と呼び出し先の関数で双方向のやり取りをしたい場合です。

実際には、あれやこれやの理由で、関数に対して情報を与えたいだけの場合でもByRefを使うことはありますけどね。
基本は上記のとおりです。






