たのしい工学

プログラミングを学んで、モノをつくりたいひと、効率的に仕事をしたい人のための硬派なブログになりました

値型と参照型と値渡しと参照渡しについて

   

C#の記述を例に参照型について説明します。たとえばクラスからインスタンスを作成するのはこの参照型に該当します。参照型に対して、値型というのがあります。値型はたとえば変数var = hogeのようなものです。値型と参照型の違いは代入されるデータの種類です。var=hogeのように変数に値を定義するとPCの中では何が起きているか想像できますか?変数varが定義されるとRAM(メモリ)の中にvarの領域が確保されます。たとえばメモリのアドレス50番にvarの領域が確保されたとします。varにhogeが代入されるとvarの実体はメモリのアドレス50番の領域なので、メモリのアドレス50番にhogeというテキストデータ(値)が格納されます。なので、var=hogeは代入されるデータが「値」なので値型といいます。もうおわかりかもしれませんが「値型は代入されるデータが値だから値型」なら「代入されるデータが参照だから参照型」だということです。参照を代入する?ってなんだ?と思っている方はナイスセンスです。

https://gyazo.com/a7a4d31242fa47da89bc7ed99fe069ae

たとえばオブジェクト指向言語では新たなインスタンスを生成するときに、しばしばA=new B()としてBというクラスからAというインスタンスを生成します。これは参照型です。ようはAというインスタンスはBというクラスを新たに参照するということの宣言です。これはAにはnewB()を代入しているということですね。newB()とは「新しいBの参照」です。Aに新しいBの参照を代入するから「参照型」です。
値型はデータを代入しますが、参照型は参照を代入します。では、参照とは何でしょうか?これはメモリのアドレスです。たとえば、
https://gyazo.com/d16a604fc157b63a220dd9641787e7b1
というコードがあったとすると、メモリアドレス上には、Aという値の領域ができます。これを仮にアドレスの51番としましょう。Bの領域を仮にアドレス52番とすると、Aの領域はこのメモリ52番のアドレスを参照することになります。では、このAをCに代入しましょう。
https://gyazo.com/f9678812093191b02b50004658c09486
すると、アドレス56番にCという領域ができて、いまAが代入されるので、Cにはメモリのアドレス52番のアドレスの参照が代入されます。 「new」がついていないから「値型」じゃないか?と思ったかもしれませんが、Aにはメモリのアドレス52番の参照が代入されているので、C=Aは参照渡しとなります。注意しなければならないのは、ここまで具体的な値はまだなにもセットされていないということです。ここで、Cに5が代入されたとしましょう。
https://gyazo.com/2f7f7b5f4b42be9e5d136f2f91ceb633
この段階ではじめて値がセットされたことになります。では、この値はどこに入るでしょうか?Cの値はいまメモリ52番の参照なので、この場合5は、参照しているアドレスに入ります。つまり5は52番のアドレスに入ります。これが値渡しだとしたらいま、C自体のアドレスは56番なので56番にCの値が入ります。いまは参照渡しによってCにはメモリのアドレス52番の参照が代入されているので、C自体のアドレスには5は代入されず、参照のアドレスに5が代入されるということです。そして、52番を参照しているのはCだけではありあません。Aも52番を参照しているので、じつはこの段階でAの値も5に決定するのです。A自体のアドレスは51番でしたが、いまはBの参照、つまり、メモリアドレス52番が代入されているので、Aも5になったというわけです。
https://gyazo.com/9d6cdd7d9019bfd2c7c5d632df0d8746
どうでしょう?参照の概念はわかりましたか?

参照型は「自分自身じゃなくて、他人の居場所を代入する」って考えるとわかりやすいかもしれません。

以上を念頭に、上記のvoid Start()関数の中をあらためてながめてみると意味がよくわかるとおもいます。

参照の概念をもっと理解するにはC言語の「ポインタ」の概念を理解するとわかるようになります。

ではでは

 - コンピュータサイエンス ,