はじめに
今回はプログラミングを学習するにあたって、初心者の方が困惑しやすいであろう「参照渡し」と「値渡し」について説明します。
結論から言うと、参照渡しは該当するデータそのものにアクセスする、ということに対して、値渡しは該当するデータのコピーを取りそれにアクセスする、という違いがあります。
この説明だといまいちわからないという方が多いと思うので、図を使って説明してみます。
例えば、図の左側の女性が、右側の男性が持っているりんごを受け取りたいとしましょう(どんなシチュエーションだよって話ですよねなしですよねw)。
ここで、参照渡しと値渡しの違いが出てきます。
参照渡し
まず、参照渡しの場合だと、男性が持っているりんごそのものを参照する、ということになります。
同じものに同時にアクセスするイメージです。
つまり、下の図のように2人で同じりんごを共有している状態になります。
この状態で、女性がりんごを食べてしまったら男性が持っていたりんごもなくなってしまいます。
これは当然なことですね。
しかし、値渡しの場合だとこのようなことは起こりません。
というのも、値渡しの場合、女性は男性が持っているりんごのコピーを作成し、それを受け取るからです。
では、次で値渡しを見ていきましょう。
値渡し
まず、下の図のように男性が持っているりんごを別のりんごへとコピーします。
(本来は、コピーということなので形状や色なども全く同じになるのですが、ここではわかりやすいように見た目だけ変えておきます)
コピーできたら、このコピーの方を女性が受け取ります。
つまり、下の図のような状態になりますね。
この状態だと、女性が持っているりんごに何をしたとしても、もともとあった男性が持っているりんごには影響がありませんよね。
つまり、この2人が持っているりんごはお互いに別のものである、ということになります。
実際のコード
ここまでは、図を使った説明をしてきたので、次は実際のコードを見てみましょう。
ここでは、例としてC言語のコードで説明します。
どの言語でも考え方は同じなので、あまり言語は気にしないでも大丈夫です。
値渡し
基本的には、変数を関数へ渡すときには値渡しとなります。
1 2 3 4 5 6 7 8 9 10 11 12 13 |
#include <stdio.h> void zero(int x) { x = 0; // xに0を代入 } int main(void) { int x = 10; // xの初期値に10を代入する printf("%d\n", x); // xの値を表示する 出力結果 : 10 zero(x); // 引数をxとしてzero関数を呼び出す printf("%d\n", x); // xの値を表示する 出力結果 : 10 return 0; } |
このコードでは、 zero という関数に値渡しで変数 x を渡しています。
つまり、 zero 関数内での x は、メイン関数内の x のコピーであるため、初期値として10が入っていますが、それを書き換えたところでメイン関数内の x は書き換わりません。
参照渡し
C言語の場合、引数で配列を渡してあげると参照渡しになります。
1 2 3 4 5 6 7 8 9 10 11 12 |
#include <stdio.h> void zero(int array[]) { array[2] = 0; // index[2]に0を代入する } int main(void) { int array[3] = {10, 20, 30}; // indexという配列をつくる初期値は10, 20, 30 printf("%d\n", array[2]); // index[2]の値を出力 出力結果 : 30 zero(array); // 配列indexを引数にしてzero関数を呼び出す printf("%d\n", array[2]); // index[2]の値を出力 出力結果 : 0 return 0; } |
このコードでは、 zero 関数に引数として配列 array を渡しています。
配列は参照渡しとなるため、直接メイン関数内の array[2] のデータが書き換わっています。
以上が、値渡しと参照渡しの違いと、実際のコードになります。
では、今回はここまでとします。
質問等がある場合は、コメントにてお願いします。
お疲れさまでした!