[C/C++]配列、ポインタ、引用、いったいどんな違いがありますか?


配列とポインタ
皆さんは初心者の頃、ポインタと配列の概念ははっきりしていたと信じていますが、学んでいると、限界がますます曖昧になり、「配列はポインタ」という錯覚を起こすこともあります.しかし、この考えは間違いであることは明らかです.配列名は値的にポインタと同じですが、VSを使用して表示すると、彼らのタイプが異なることがわかります.
int arr[3] = {
     1, 2, 3};
int *ptr = arr; 

arrのタイプはint[3]であり、ptrのタイプはint*であり、多くの場合、互いに変換することができるが、2つの重要なオペレータが異なる結果をもたらす.
  • sizeof演算子はarrに対して12,ptrに対して32ビットg++で4を与える.
  • &(アドレス演算子)結果を見てみましょう.
    演算子
    を選択します.
    結果
    arr
    int[3]
    0xffc0e994
    &arr
    int[3]*
    0xffc0e994
    &arr[0]
    int*
    0xffc0e994
    ptr
    int*
    0xffc0e994
    &ptr
    int**
    0xffc0e990
    最も注目されているのは、&arrと&ptrが一致しない
  • です.
    では、なぜこのような違いがあるのでしょうか.実はとても簡単で、配列とは何ですか?配列はメモリ内の連続した空間であり、同じ種類の要素を格納しています.しかしポインタが異なり、彼は別のオブジェクトのアドレスを格納しているオブジェクトである.私たちがarr、すなわち配列名を直接使用するとき、コンパイラはarrのアドレスとして解釈しますが、arr自体はそのアドレスではなく、その連続した空間です.ptrは異なり、彼自身がアドレスです.また,配列タイプはコピー初期化をサポートしていないため,配列が関数のパラメータとして機能することは不可能であることが決定される(実パラメータにはコピー初期化が必要であるため).したがって,我々が見たすべての配列をパラメータの関数呼び出しとして,コンパイラはまずポインタに隠して呼び出しを行うのを助けるので,配列をパラメータとして関数に伝達した後,彼の挙動はポインタと一致した.では、なぜ配列はコピー初期化をサポートしないのでしょうか.C++の配列はCから継承され,Cはプロセス向けの言語であり,配列と配列の長さは分離されている.これにより,1つの配列しか知らない場合には,その長さが得られない.したがって、コピーは自然にできません.C++のvectorタイプは内部に長さがあるので、コピーして初期化できます.
    ポインタと参照
    (以下、C++98の古典的な左の引用について説明します)これも非常に困惑している点で、ポインタと引用は非常に似ているように見えますが、このように異なり、ポインタと引用の違いを背負うことができると信じています.
  • の最も本質的な違い:ポインタはオブジェクト(データを格納し、何らかのタイプのメモリ空間を有する)であり、参照は別名にすぎず、参照とポインタの他の違い
  • を決定する.
  • 参照は初期化される必要がありますが、ポインタは必要ありません.
  • には空のポインタが存在しますが、空の参照はありません.
  • 参照の作成および破棄は、構造および構造関数を呼び出すことはありません.
  • 参照オブジェクトにバインドされると、他の変数にバインドできませんが、ポインタは可能です.

  • しかし、ポインタは引用と何の関係があるのでしょうか.答えは関係ありません(笑)底から見ると、引用はポインタと同じように変数のアドレスでアクセスします.しかし、コンパイラ、すなわちC++の言語面では引用に多くの制限がなされている.言語を学ぶには、上層部の設計と下層部の設計(このような用語はなく、私はでたらめを言っている)に注意する必要があります.下層部では引用とポインタが同じように見えますが、彼もアドレスを持っていなければなりませんが、私たちの上層部の設計は「引用は対象ではありません」という要求を保証するために、これを禁止しています.したがって、参照を理解するには、「参照はオブジェクトではなく、オブジェクトのアドレスではなく、オブジェクトのコピーではなく、彼は別名にすぎない」ということを知っておく必要があります.