C + +第2部でポインタと参照

2009年5月2日は°で掲示されるC / C + +

について話し始めたポインタと参照、約一連の記事でこの試みを継続ポインタ 、参照は今日話し合う。

参照は、エイリアスオブジェクトの別名です。 そして誰がこの私ではないと言うが、非常にであるBjarne Stroustrupはあなたの5.5の話題について、 コンテンツ私は唯一のカバーはCの形に砕ける波を持っていることを今日に気づくように良いです、 私はそのカバーが好き!

参照を宣言

特定の型への参照は、 文字 &(アンパサンドまたは追加することによって宣言されているアンパサンドを参照の型の名前の後に)。 ポインタの宣言と同様に、我々は評価していない演算子として文字を扱っていることに注意してください。 ポインタまたは参照の宣言のない演算子はありません それは単なる表記言語です。 型Tを考えると、式は、T&Tの参照を意味します 次に例を示します。

 i ; // Declaram referências para a variável i. // Todas as formas são equivalentes, mas preferimos a primeira. // Note que os tipos das referências tem que ser os mesmos // que os das variáveis referenciadas. int & ra = i ; int & rb = i ; int & rc = i ; // Diferentemente de ponteiros, a linha abaixo gera um // erro de compilação. 。。/ /整数変数は、元の宣言/ /また、char型、float型、などが考えられます。 します 。int i;。/ /最初に/ /注意/ /すべてのフォームは等価であるが、好む変数iへの参照を宣言するタイプ参照が参照される同じ/ /変数である必要が int型 &RA = ;。&RB = します 。int i; int型 &RC = I / /ポインタとは異なり、行が下に/ /コンパイルエラーが生成されます。  & r1, & r2 ; ?その理由 Int&R1&R2  知っ ています   

のC + +の参照ポインタが少し覚えているが、彼らは全く異なっています。 ポインタを使用して何が起こるかとは異なり、参照は、宣言時に初期化する必要があります。 それはコンパイル時にエラーを生成する初期化せずに参照を宣言しようとする、すなわち、コンパイラはあなたの顔に唾を吐きかけるだろう"プレイボーイ失われたロスト。" この規則の唯一の例外として宣言された参照用のexternそれらはプログラム内のいくつかの他のポイントで初期化されるため、、それは別の暴言です。

もしコンパイラが初期化せずに外部参照を宣言することにより、カンニングしようとすると文句を言うことはありません。 それを使用したことがない場合、[OK]。 コンパイラは、スマートであり、それが使用されていないことに注意している場合、それもシンボルのリストからそれを削除することができます。 しかし、それはプログラムのどこで使用されている場合、リンカは、あなたの顔は笑いで笑うだろう"に未定義の参照を"nome_da_variavel。"" ので、適切に物事を行う。 参照を宣言? そう、それをiniclalize。 externを? あなたは何をやっているか知ってよろしいですか?

この背後にあるロジックは、リファレンスが何かの名前であることが意図されていることです。 もし起動しない場合、それは何のために名前を付けることはありません、それは意味をなさない。 非常に重要な詳細は、参照を開始すると、それに値を割り当てることではないということです。 prórioであるBjarneが言うように、演算子が参照する上で動作しない、すなわち、参照しながら、減算、等を、割り当てる追加する方法はありません。 参照がオブジェクトのエイリアスであるように、各演算子がないの参照で、NESEオブジェクトとして動作します。 いったん初期化されると、参照は常に同じオブジェクトを参照する。

参照だけでなく、問題上のポインタを持つ最初のトラップは、サイズです。 ポインタ(および他のデータ構造)のサイズはsizeof演算子で得られる一方で、基準のサイズが基準にsizeof演算子を適用するときのように、従来の技術では得ることのできない、我々は、実際には我々は前の段落で見たように、それが参照するオブジェクトに演算子を適用する。

  17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
   char c;
 します 。int i;
 ダブル D;

 rc = c ; CHAR&RC = C;
 ri = i ; int型 = 私;
 rd = d ; ダブル &RD = D;

 / / sizeof演算子は引数の型のサイズは述べています。
 "Size of char: " << sizeof ( c ) << " bytes" << endl ; 裁判所 <<"charサイズ:"<<sizeof 演算 (C)<<"バイト"<<endl を。
 "Size of int: " << sizeof ( i ) << " bytes" << endl ; 裁判所 <<"int型のサイズ:"<<sizeof  (I)<<"バイト"<<endl を。
 "Size of double: " << sizeof ( d ) << " bytes" << endl ; 裁判所 <<"二重のサイズ:"<<sizeof  (D)<<"バイト"<<endl を。

 endl ; 裁判所 <<endlを。

 "Size of char&: " << sizeof ( rc ) << " bytes" << endl ; 裁判所 <<"charの&のサイズ:"<<sizeof  (RC)<<"バイト"<<endl を。
 "Size of int&: " << sizeof ( ri ) << " bytes" << endl ; 裁判所 <<"int型&のサイズ:"<<sizeof 演算 (RI)<<"バイト"<<endl を。
 "Size of double&: " << sizeof ( rd ) << " bytes" << endl ; 裁判所 <<"二重&のサイズ:"<<sizeof 演算 (RD)<<"バイト"<<endl を。 

参照のサイズのための技術は、このテキストの範囲を超えていますが、私は後でその話をしていきます。 今のところ、私はちょうど該当する場合には、リファレンスのサイズはポインタのサイズと同一である、ことを実証するためにノーと言うでしょう。

物語の良い部分は、はるかに少ない、関連リンクまたは参照されるオブジェクトのサイズよりも多くの場合、ポインタと参照のサイズです。 私個人的に、その情報を使用するために必要なことがないが、開発用または組込みシステムのための異なるアーキテクチャ上で、それはより興味深いとなっています。

参照の使用

参照の使用は、すでにオペレータがアドレスまたは参照解除を抽出するために必要されていないポインタのそれよりはるかに簡単です。 変数の参照は、参照で行った操作が常に参照されるオブジェクトに影響を与えることに注意し、通常の変数として使用されています。

  17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
  int型x、y;
 rx = x ; int型 &X = RX;
 ry = y ; int型 とy = リュー;

 ; X = 13;
 ; Y = 10;

 ; // A atribuição é automaticamente aplicada em x. RX = 42 / /代入は自動的にxで適用されます
 // O incremento é automaticamente aplicado em y. RY + + / /インクリメントは、自動的にyに適用されます。

 "x: " << x << endl ; // Valor de x. 裁判所 <<"X:"<<x <<endlを / /値のxの
 "y: " << y << endl ; // Valor de y. 裁判所 <<"Y:"<<Y <<endlを / /値yの
 "rx: " << rx << endl ; // Valor de rx == x. 裁判所 <<"RX:"<<RX <<endlを / /値== xのRX
 "ry: " << ry << endl ; // Valor de ry == y. 裁判所 <<"RY:"<<RY <<endlを / /値== RY Y. 

このような参照を使用するプログラマに対して透過的である、彼が参照されていることを知る必要はありませんでした。 単に普通の変数と同様に使用してください。 私の限られた想像力で誰もができるか見ることはできません破門不適切な参照を使用する。 常にいくつか持っているが、 豚肉の精神の参照とたわごとを行うことができます、が引っかかってしまう方がはるかに簡単ですSacIでポインタを扱うとき。

アドレスと参考文献

の観点からマーフィーそれらを行うために潜在的に危険な少しがあるので、参照は、、醜い退屈でくだらないです。 多くの驚きのアドレスは(意志?)あるとしてもとして。 以下のコードを考えてみます。

  17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
  10 ; です。int a = 10;
 13 ; int型 B = 13;

 ra = a ; int型 &RA = A;
 rb = b ; int型 &B = RB;

 ; RA = 42;
 ; RB = 7;

 "ra = " << ra << endl ; // O valor de ra == 42. 裁判所 <<"RA ="<<RA <<endlを / / RAの値== 42。
 "rb = " << rb << endl ; // O valor de rb == 7. 裁判所 <<"RB ="<<RB <<endlを / / RB == 7の値。
 "a = " << a << endl ; // O valor de a == ra == 42. 裁判所 <<"A ="<<A <<endlを / / RAの値== A == 42。
 "b = " << b << endl ; // O valor de b == rb == 7. 裁判所 <<"B ="<<B <<endlを / / rbの値== B == 7。

 "&a = " << & a << endl ; // O endereço de a. 裁判所 <<"&A ="<<&A <<endlを / / aのアドレス
 "&b = " << & b << endl ; // O endereço de b. 裁判所 <<"A&B ="<<&B <<endlを / / bのアドレスを
 "&ra = " << & ra << endl ; // O endereço de ra == &a. 裁判所 <<"&RA ="<<&RA <<endlを / / RA ==&aのアドレスを
 "&rb = " << & rb << endl ; // O endereço de rb == &b. 裁判所 <<"&RB ="<<&RB <<endlを / /アドレスRB == A&B 

17および18行目で、私は、2つの整数の変数を(一例でこれを行っている可能性が...).宣言 ライン20:21で私は前の2つの変数を参照する、二つの参照を宣言します。 その後、変数RAとRBは、変数aとbのためだけのエイリアスです 前述のように、参照に適用されたすべての演算子が実際に参照されるオブジェクトに作用する、各ペアは、変数参照は、常に同じ値を持つように。

興味深い部分は、参照のアドレスが正確に同じアドレスが参照変数の代わりに自らのアドレスを持っていたポインタであるということです。 なぜ? あなたはに落ちたのでガッチャトリックスター ない演算子についてのその原料は参照に適用される覚えていますか? よく、ここで使用される&演算子も参照の元の変数としないように直接適用される"アドレス"、です。 参照のサイズを取得するために忍者を使用したのと同じテクニックは、それらのアドレスを取得するために必要とされる。

再び楽しい部分は、参照機構は、プログラマのために可能な限り透明になるように設計されていることです。 サイズと参照の物理アドレスは、C言語で"通常の"プログラミングの観点から無関係な情報です+ +。

ポインタと参照の相違点と類似点

両方の参照はCの間接の機構としてのポインタです+ +、またはメカニズムは、特定のシンボル(変数)から私は他のオブジェクトを操作することができる時というのに使用されます。

ポインタの主な用途は、通常、さまざまな形や特別な瞬間のオブジェクトの動的なメモリ、創造と破壊を管理、操作に関連し、同様に(それを引用符)"参照渡し"されています。 参照は参照渡しで主に使用されているので(私はな​​ぜか不思議に思う)と演算子オーバーロード。

基本的に、我々は参照を使用して実行できるすべてのポインタを使用してエミュレートすることができます。 すでにrecíprocraは常に真ではありません。 それらの大きな利点は、しかし、間接はプログラマに対して完全に透過的になることです。

ポインタと参照の違いについての理解を深める助けに興味深い寓意は、ニックネームです。 例えば:人、と言う、ことを想像カルロスカエターノブレドルンヴェーリーが 。、私達の変数は元のオブジェクトであるドゥンガがすでにカルロスカエタノブレドルンヴェーリーへの参照である、それは同一人物である同じオブジェクトの別名です。 既に着実に手のファンが引用されドゥンガの母は(カルロスカエターノブレドルンヴェーリーまたはヴェッリ、何でも)、、実際に間接的に標的とされ、それ賛辞作った、語彙データの特定の演算子のために、それへのポインタと考えることができますそれまで。

リンク

コメント

  • http://caloni.com.br ワンダレイCaloni

    素晴らしい記事!

    残念なことに、参照は見かけほど無害ではありません。 次のような状況を想像してみてください。

    1。 誰かが非静的ローカル変数への参照を返します。

      QueroEconomizarCopiasDeString ( )文字列 アンプ; QueroEconomizarCopiasDeString()
     {
       文字列RET;
        / /ハックハックハック
        // espertão... RET / /頭のいい男を 返す ...
     } 

    この場合、範囲は、誰かが参照を使用する前であっても終了します。

    解決策は、パラメータとしての参照を取得し、変数"out"が、コピーを1つだけにすることです。

    2。 誰かが通常の変数などの動的メモリーを使用したい:

      int型のmain()
     {
        pi = new int ; int型 *π= 新しいint;
    
        /コードの/行数は、πが誰であるかを忘れるために
    
        amp ; ri = * pi ; // acho ponteiros complicado int型  アンプ;=π* / /ポインタは難しいと思う
    
        RIとPIを忘れないようにコードの/ /行以上
    
        πを 削除 する。
    
        / / ... Tcharammm
    
        ; // é a resposta para tudo, não? RI = 42 / /はない、すべてへの回答なのか?
     } 

    これらの例では、獣のように見えるが、それは見かけほどそうではない。 ちょうどコードはデザインパターンや他のがらくたとごまかされ、何が起こったのか知らなくても、それが爆発する。

    [] S

  • http://caloni.com.br ワンダレイCaloni

    素晴らしい記事!

    残念なことに、参照は見かけほど無害ではありません。 次のような状況を想像してみてください。

    1。 誰かが非静的ローカル変数への参照を返します。

      QueroEconomizarCopiasDeString文字列&()
     {
       文字列RET;
        / /ハックハックハック
        // espertão... RET / /頭のいい男を 返す ...
     } 

    この場合、範囲は、誰かが参照を使用する前であっても終了します。

    解決策は、パラメータとしての参照を取得し、変数"out"が、コピーを1つだけにすることです。

    2。 誰かが通常の変数などの動的メモリーを使用したい:

      int型のmain()
     {
        pi = new int ; int型 *π= 新しいint;
    
        /コードの/行数は、πが誰であるかを忘れるために
    
        ri = * pi ; // acho ponteiros complicado int型 =π* / /ポインタは難しいと思う
    
        RIとPIを忘れないようにコードの/ /行以上
    
        πを 削除 する。
    
        / / ... Tcharammm
    
        ; // é a resposta para tudo, não? RI = 42 / /はない、すべてへの回答なのか?
     } 

    これらの例では、獣のように見えるが、それは見かけほどそうではない。 ちょうどコードはデザインパターンや他のがらくたとごまかされ、何が起こったのか知らなくても、それが爆発する。

    [] S

  • http://blabos.org うっかり漏らす

    Caloniは、あなたも性急な男だ :)

    はい、あなたは正しいです。 私はそれが目的で行ってみましょう。
    私は、constポインタまたは参照に、まだ話したことのなかった、またポインタと配列の間でさえ、その関連付けが、私は話すだろう。

    褒めてくれてありがとう、それは非常にやる気れている。

    大きな抱擁

  • http://blabos.org うっかり漏らす

    Caloniは、あなたも性急な男だ :)

    はい、あなたは正しいです。 私はそれが目的で行ってみましょう。
    私は、constポインタまたは参照に、まだ話したことのなかった、またポインタと配列の間でさえ、その関連付けが、私は話すだろう。

    褒めてくれてありがとう、それは非常にやる気れている。

    大きな抱擁

  • http://caloni.com.br ワンダレイCaloni

    私の素朴さが、私はそれはすでにあなたが言ったときに問題が閉じ、指定されたと思っていた"、それらに潜在的に危険はほとんど関係がないので、マーフィーの観点からは、参照が、、醜い退屈でくだらないです。"いずれでもそれはCとCの違いのために思い切っている人や、実際に非常によく説明しているための方法、私は既に初心者のためのあなたの記事を推奨している+ +。

    私は続編を待つ。

    [] S

  • http://caloni.com.br ワンダレイCaloni

    私の素朴さが、私はそれはすでにあなたが言ったときに問題が閉じ、指定されたと思っていた"、それらに潜在的に危険はほとんど関係がないので、マーフィーの観点からは、参照が、、醜い退屈でくだらないです。"いずれでもそれはCとCの違いのために思い切っている人や、実際に非常によく説明しているための方法、私は既に初心者のためのあなたの記事を推奨している+ +。

    私は続編を待つ。

    [] S

  • http://www.jorgepereira.com.br ホルヘペレイラ

    Blaberパートナー!

    非常に良い、記事、おめでとうございます!

    [] S

  • http://www.jorgepereira.com.br ホルヘペレイラ

    Blaberパートナー!

    非常に良い、記事、おめでとうございます!

    [] S

  • http://www.caloni.com.br/blog/archives/ultimas-pesquisas-na-blogosfera-nacional Caloni.com.br国のブロゴスフィアでブログ» Blog Archive »最新の研究

    [...]の[...]のPointeirosと参考文献

  • http://www.brunodanielmarinho.com ブルーノ

    さらに待っている法的

  • http://www.brunodanielmarinho.com ブルーノ

    さらに待っている法的

  • http://blabos.pip.verisignlabs.com/ うっかり漏らす

    こんにちは、

    褒めてくれてありがとう。

    時間は短いですが、私はできるだけ早く手続きを記述します。

  • http://blabos.pip.verisignlabs.com/ うっかり漏らす

    こんにちは、

    褒めてくれてありがとう。

    時間は短いですが、私はできるだけ早く手続きを記述します。

  • カイロローシャ

    こんにちは、私は深刻な問題を抱えているとポインタ/参照を解決することができます。

    私はリングで近所を行う必要があります。 例えば、私はクラスがあり、クラスAの三つのオブジェクトを宣言
    [0]と[1]の隣人。
    [1]及び[2]の隣人。
    [2]と[0]の隣人。

    私は、ポインタと参照を使用してみましたが、ときに、例えば、更新[1]、A [0]の変更"を参照してください"することはできません。

  • ブレブのBlaber http://blabos.org

    いいえ何をしたいの詳細ないとあなたがやったこと、それはあなたを助けるのは難しい。

Disqusを搭載ブログのコメント