2016-10-26 4 views
-2

に私はしばしば、配列の名前は、したがって配列とポインタはC++

int a[10]; 

int * const p= a; 

のような文があるという意味では同じでなければならないメモリのブロックに一定のポインタであることを聞きますpは配列a []と同じメモリブロックを指すポインタであり、メモリ内の別の場所を指すように変更することはできません。

しかし、あなたは異なる結果を得るこれら二つのポインタsizeofは印刷しようとします

cout<< sizeof(a); // outputs size of 10 integer elements 

ので

cout<< sizeof(p); // outputs sizeof pointer to int 

ながら、なぜコンパイラは異なり、これらの2を扱うのですか?コンパイラの観点から見た配列とポインタの真の関係は何ですか?

+8

あなたはしばしば誤解を招いたことがあります。または単に誤解したことがあります。配列はポインタではありません。 – user2079303

+0

タイプ「T」およびサイズ「N」の配列は、シーケンシャルメモリに配置された「N」個の「T」型オブジェクトです。ポインタがそのメモリを指すようにできるだけで、配列をポインタにすることはできません。 – DeiDei

+0

C++は強く型付けされた言語であり、特にsizeofは型を参照するため、これらは異なっています。 aとpが交互に使用できるランタイムケースがたくさんあります(正しい範囲内にある限り)が、それらはまだ異なるタイプです。 –

答えて

5

私は、多くの場合、配列の名前がメモリ

のブロックに一定のポインタであることを聞いてあなたはしばしば誤解してきた - またはあなたが単に誤解しました。配列は、メモリブロックへの定数ポインタではありません。配列は、一連のサブオブジェクトを含むオブジェクトです。すべてのオブジェクトはメモリのブロックです。ポインタは、オブジェクトのアドレスを含むオブジェクトであり、オブジェクトを指しています。

したがって、aは配列で、paの最初のサブオブジェクトを指しています。

int a[10]; 

int * const p= a; 

は、配列[]は、また、指すように変更されなくてもよいように、pは、メモリの同じブロックを指すポインタであるという意味で等しくなければなりません。メモリ内の別の場所。

それは同じのあなたの定義である場合には非配列が同様のオブジェクトに対して、それが成り立つ:

char c; 
int * const p = &c; 

ここpcと同じメモリへのポイント」とポイントに変更することはできませんメモリ内の別の場所に移動します。これは、charオブジェクトがポインタと「等しい」ことを意味しますか?いいえ、配列はどちらでもありません。

ただし、配列の同じ要素を指す定数ポインタ(配列の名前)ではありませんか?

いいえ、配列の名前は定数ポインタではありません。 charの名前のように、定数ポインタではありません。

配列の名前は、配列の最初の要素のアドレスを保持します。

もっと一般的に言えば、配列に固有のものではありません。変数の名前は、その変数名が持つオブジェクトの「アドレスを保持する」。アドレスは実行時にメモリに保持されません。これはコンパイル時にコンパイラによって保持されます。変数を操作するとき、コンパイラはオブジェクトが正しいアドレスにあることをコンパイラで確認します。

アレイのアドレスは常に、アレイの最初の要素(サブオブジェクト)があるアドレスと同じです。したがって、実際にはその名前は - 少なくとも概念的には - の同じアドレスを保持します。

*(a+1)を使用している場合、これはa[1]と同じですか? [タイプミス]

右。私は詳しく説明します:一つは、ポインタの場合に別の方法を書くことです。ああ、しかしaはポインタではありません! catchは次のとおりです。配列オペランドは暗黙的に最初の要素へのポインタに変換されます。この暗黙の変換は、減衰と呼ばれます。これは配列型の特殊な機能です。ポインタと配列の違いを理解するのが難しい特殊な機能です。

したがって、配列の名前はポインタではなくても、ポインタに崩壊する可能性があります。特定のコンテキストでのみ、名前が常にポインタに崩壊するとは限りません。 operator[]を使用すると減衰し、operator+を使用すると減衰します。サブオブジェクトの型へのポインタを受け入れる関数に配列を渡すと、減衰します。 sizeofを使用すると減衰しません。参照によって配列を受け入れる関数に渡すと減衰しません。

+0

しかし、(配列の名前)ではない、配列の同じ要素を指す定数ポインタ? – Arash

+0

@Arash No.編集を参照してください。 – user2079303

+0

@Arash配列の名前は、あなたが考えている定数ポインタに*暗黙的に変換されます。しかし、それだけではポインタではありません。 – HolyBlackCat