(Translated by https://www.hiragana.jp/)
参照 (計算機科学) - Wikipedia

参照さんしょう(さんしょう、えい: referenceリファレンス)は、場所ばしょにあるデータをしている情報じょうほうふくちいさなオブジェクトであり、それ自身じしんなかに(している)データ自体じたいふくまない。参照さんしょうすことをデリファレンス (dereference) とぶ(間接かんせつ参照さんしょう参照さんしょう)。参照さんしょう様々さまざまなデータ構造こうぞう構成こうせいする基本きほん要素ようそであり、プログラムない各部かくぶ情報じょうほうをやりりするための基本きほんでもある。

なお、C++には、参照さんしょうがたというものがあるが、以下いか説明せつめいするのはC++のそれではなく、一般いっぱん概念がいねんである。C++の参照さんしょうについては、ポインタ (プログラミング)#参照さんしょう参照さんしょうのこと。

住所じゅうしょ使つかったたとえはなし

編集へんしゅう

参照さんしょういえ住所じゅうしょている。住所じゅうしょ非常ひじょうちいさな識別子しきべつしであり、それがしているモノにはさらに豊富ほうふ情報じょうほうがあるだろう。たとえば、そのいえればいろがわかるが、住所じゅうしょだけではいろはわからない。住所じゅうしょたんいえつけることを可能かのうにするだけである。しかし、もしいえいろりたければ、住所じゅうしょさえあればつけして実際じっさいにそのいえればよい。つまり、住所じゅうしょいえいろるための充分じゅうぶん情報じょうほうげんとなる。住所じゅうしょからいえさがすことは、参照さんしょうをデリファレンスすることにている。

もっと複雑ふくざつれいとして、引越ひっこしのたびあたらしいいえ住所じゅうしょふるいえのこしておくとする。だれかが最初さいしょいえたずねると、いてある住所じゅうしょからつぎいえつぎいえへとたどっていき最終さいしゅうてき現在げんざいいえにたどりくことができる。これは参照さんしょう使用しようした単純たんじゅん線形せんけいリストている。

住所じゅうしょべつ利点りてんは、それが実際じっさいいえよりもずっとあつかいやすいことである。たとえば、町内ちょうない人々ひとびとせい五十音ごじゅうおんじゅんならべたいとしよう。ひとつの方法ほうほうとして、巨大きょだいなクレーンを使つかって町内ちょうないいえ全部ぜんぶ物理ぶつりてきならえる方法ほうほうがある。もっと簡単かんたん方法ほうほうとしては、町内ちょうないひとたちの住所じゅうしょのリストをつくり、せい五十音ごじゅうおんじゅんにそれをならえるという方法ほうほうがある。参照さんしょうにも同様どうよう利点りてんがある。データへの参照さんしょう操作そうさすることによってデータ自体じたい変更へんこうすることなく様々さまざまなことができるし、場合ばあいによってはそのほう効率こうりつてきである。

日常にちじょう生活せいかつ参照さんしょうれいであふれている。電話でんわ番号ばんごう電子でんしメールアドレス、URLなどなど。いずれも遠隔えんかくにあるリソースをし、それらへのアクセスを可能かのうとする。

参照さんしょう利点りてん

編集へんしゅう

参照さんしょうによって、オブジェクトを格納かくのうする場所ばしょ格納かくのう方法ほうほう、コードないでのわたしなどの柔軟じゅうなんせいす。参照さんしょうによって実際じっさいのデータにアクセスできるなら、データ自体じたい移動いどうさせる必要ひつようはない。また、複数ふくすうのコードが参照さんしょうによってひとつのデータを共有きょうゆうすることもできる。

ポインタはオブジェクトのメモリじょうアドレスだけを格納かくのうしたものである。これはもっと基本きほんてき間違まちがえやすい参照さんしょうだが、もっと強力きょうりょく効率こうりつてき参照さんしょうでもある。スマートポインタ不透明ふとうめいデータ構造こうぞう一種いっしゅで、ポインタのようにはたらくが、特定とくていのメソッドをとおさないとアクセスできない。

ファイルハンドルはファイルの内容ないよう抽象ちゅうしょうする参照さんしょうである。それはファイルへのロック要求ようきゅうするさいにはファイル自体じたいすと同時どうじに、ファイルをさいにはファイルない特定とくてい位置いちす。

形式けいしき表現ひょうげん

編集へんしゅう

より一般いっぱんすると、参照さんしょうは、あるデータの一意いちい検索けんさく可能かのうとするべつのデータとみなすことができる。これにはデータベースしゅキー連想れんそう配列はいれつのキーなどもふくまれる。データの集合しゅうごう D について、D から D ∪ {null} への一意いちいさだまる関数かんすう参照さんしょう定義ていぎとなる。ここで null意味いみのあるものをしていないデータである。

このような関数かんすうべつ表現ひょうげんとして、「到達とうたつ可能かのうせいグラフ; reachability graph」とばれる有向ゆうこうグラフがある。ここで、かくデータは頂点ちょうてんとしてあらわされ、データ u から データv へのエッジがあるとき、uv参照さんしょうしている(グラフ理論りろん)。最大さいだい出次数でじすうは 1 である。このように参照さんしょうをグラフとしてとらえることはガベージコレクション到達とうたつ不可能ふかのうなオブジェクトからのアクセスを分離ぶんりするのに有効ゆうこうである。

外部がいぶ収納しゅうのう内部ないぶ収納しゅうのう

編集へんしゅう

おおくのデータ構造こうぞうなかで、おおきく複雑ふくざつなオブジェクトはちいさなオブジェクトぐんから構成こうせいされている。そのようなオブジェクトぐん格納かくのう方法ほうほう以下いかのように2つにけられる。

  1. 内部ないぶ収納しゅうのう(internal storage)[よう出典しゅってん]では、ちいさなオブジェクトの内容ないようおおきなオブジェクトの内部ないぶ格納かくのうされている。
  2. 外部がいぶ収納しゅうのう(external storage)[よう出典しゅってん]では、ちいさなオブジェクトは独自どくじ場所ばしょかれ、おおきなオブジェクトはそれへの参照さんしょうのみを格納かくのうする。

内部ないぶ収納しゅうのうは、参照さんしょうのための領域りょういき動的どうてきメモリアロケーションのためのメタデータを必要ひつようとせず、デリファレンスやちいさなオブジェクトようのメモリ確保かくほようする時間じかん節約せつやくでき、効率こうりつてきである。内部ないぶ収納しゅうのうは、同種どうしゅおおきなオブジェクトをメモリない連続れんぞくして配置はいちすることで「参照さんしょう局所きょくしょせい」をたかめる効果こうかもある。しかし、外部がいぶ収納しゅうのうこのまれる状況じょうきょう以下いかのようにさまざま存在そんざいする。

  • データ構造こうぞう再帰さいきてき(つまり自身じしん内包ないほうする可能かのうせいがある)ならば、内部ないぶ収納しゅうのう不可能ふかのうである。
  • おおきなオブジェクトがかぎられた領域りょういき格納かくのうされている場合ばあいたとえばスタック)、オーバーラン(オーバーフロー)をふせぐためにその内容ないようだい部分ぶぶん外部がいぶ収納しゅうのうにして物理ぶつりてきなサイズを削減さくげんする必要ひつようがあるかもしれない。
  • ちいさなオブジェクトのサイズが可変かへんである場合ばあい、それを内部ないぶ収納しゅうのうするとおおきなオブジェクトを可変かへんサイズとする必要ひつようしょうじ、効率こうりつわるくなることがある。
  • 参照さんしょう使つかうことで仕様しよう変更へんこうなどに柔軟じゅうなん対応たいおうできる。

いちれいとしてJavaでは、プリミティブがた内部ないぶ収納しゅうのうであり、オブジェクト(クラスがた)や配列はいれつ外部がいぶ収納しゅうのうである。

言語げんごサポート

編集へんしゅう

アセンブリ言語げんごでは、参照さんしょうはメモリアドレスや配列はいれつのインデックスで表現ひょうげんされる。これを使つかうには注意ちゅうい必要ひつようである。メモリアドレスはなにしているかわからないし、しているもののおおきさも構造こうぞう意味いみもアドレスからはわからない。そのような情報じょうほうはロジック自体じたいむ。その結果けっか間違まちがったプログラムが参照さんしょう間違まちがって解釈かいしゃくしてエラーが発生はっせいし、プログラマは途方とほうにくれることになる。

最初さいしょ不透明ふとうめい参照さんしょうのひとつとして、LISP言語げんごconsセルがある。これは単純たんじゅんすればの2のLISPオブジェクトへの参照さんしょうから構成こうせいされるデータ構造こうぞうであり、のconsセルへの参照さんしょうつことが出来できる。この構造こうぞう単純たんじゅん線形せんけいリスト構成こうせいすることもできるし、「ドットリスト」とばれる分木ぶんぎ構成こうせいすることもできる。

初期しょき言語げんごFORTRAN明示めいじてき参照さんしょうっていないが、参照さんしょうわた暗黙あんもくのうちにそれを使つかっている。

C言語げんご導入どうにゅうされたポインタは、原始げんしてき参照さんしょう形態けいたいのひとつである。これはアセンブリ言語げんごなまアドレス (raw address) 表現ひょうげんているが、ポインタの参照さんしょうしているデータがあやまって解釈かいしゃくされることのないよう、コンパイル使用しようされる静的せいてきデータがた概念がいねん導入どうにゅうしているというてんことなる。しかし、C言語げんごは「よわかたシステム」を採用さいようしていることから、かた変換へんかん(あるデータがた明示めいじてきのデータがた変換へんかんすること)によって不正ふせいなポインタを容易ようい生成せいせいすることができるため、あやまった解釈かいしゃく依然いぜんとしてしょうじうる。Cの後継こうけいともえるC++は、あらたなかた変換へんかん演算えんざん導入どうにゅう標準ひょうじゅんライブラリでのスマートポインタ導入どうにゅうなどによりポインタのかた安全あんぜんせい強化きょうかしようとこころみているが、Cとの互換ごかんせい維持いじのため意図いとてきにこれらの安全あんぜん機構きこうくことができる能力のうりょく依然いぜんとしてゆうしている。なお、C++には、さらにかたとしても「参照さんしょう」というものがある(#C++の「参照さんしょう参照さんしょう)。

ガベージコレクションをサポートするようなおおくの高水準こうすいじゅん言語げんごでは、reference などとしょうされる不透明ふとうめい参照さんしょう採用さいようしている。これらの参照さんしょうはC言語げんごのポインタのようなデータがたであるが、参照さんしょうなまのアドレス変換へんかんしたり、ぎゃくにアドレスから参照さんしょう生成せいせいしたり、といった危険きけん変換へんかんができないというてんでC言語げんごよりずっと安全あんぜんになっている。このように「管理かんりされた」言語げんご (managed language) では、参照さんしょう実際じっさいにはすべきデータへのポインタへのポインタになっていることがおおい。C/C++かられば、これらの言語げんご段階だんかいポインタを参照さんしょう使つかっていることになる(典型てんけいてき実装じっそうとしては)。ガベージコレクタだけが不透明ふとうめいせいなかあいだのポインタに直接ちょくせつアクセスすることができる。一般いっぱん参照さんしょう同士どうし演算えんざんもサポートされていない。

FORTRAN参照さんしょうえば、オブジェクトの別名べつめい (alias) を意味いみすることがおおい。たとえばスカラ変数へんすう配列はいれつくだりけたなどである。参照さんしょうをデリファレンスする方法ほうほうはなく、参照さんしょうされているものを直接ちょくせつ操作そうさするという概念がいねんもない。FORTRANの参照さんしょうは null の場合ばあいもある。言語げんごのように参照さんしょうによって線形せんけいリスト、キュー、構造こうぞうなどの動的どうてき構造こうぞう処理しょりすることができる。

Javaのデータがたには、大別たいべつして参照さんしょうがたプリミティブがた存在そんざいする。クラスかたインタフェースかたかた変数へんすうジェネリクスかた引数ひきすう)、配列はいれつかた参照さんしょうがた(reference types)である[1]

C#のデータがたには、大別たいべつして参照さんしょうがたがた、ポインタがた存在そんざいする。クラス、インターフェイス、配列はいれつデリゲート参照さんしょうがたである。数値すうちがた論理ろんりがたふく構造こうぞうたい列挙れっきょがたがたである。

関数かんすうがた言語げんご

編集へんしゅう

C++の「参照さんしょう

編集へんしゅう

出典しゅってん

編集へんしゅう

関連かんれん項目こうもく

編集へんしゅう