2013-10-14 15 views
16

配列はどのように動作するのでしょうか?私は仮説で終わり、私が正しいかどうかを知りたいと思います。配列はc/C++でどのように内部的に動作するのですか

アレイは隣接するメモリケース(ボックス)のシーケンスであり、各ボックスはストックタイプのサイズを持ちます(つまり、INTの1つのボックスにsize = sizeof(int)、3つのINTsの配列メモリ内の3つのsizeof(int)に隣接する)

ここで、特定の型の配列(Cではmalloc、C++ではnew)に動的にメモリを割り当てることができます。

私は、配列が配列の最初のボックスのアドレスと最初の値(後のボックスの値)をブラケット[0]で呼び出すときにorigin配列が "型*配列"または "型配列[]"または "型配列[サイズ]"と宣言されているかどうか)を定義するかどうかにかかわらず、その配列は "0" == *(配列+ 0)ポインタまたは配列( "type * array"または "type array []"または "type array [size]")は、最初のボックスのアドレスです。

大括弧([])で宣言されていても、配列は実際にはメモリ内にn個のポインタのシーケンス(アドレスとしてではなく値として持つ) )実際の値+これらのメモリボックス(B0、...、Bnそれぞれが実際の値を含む)を含むメモリボックスBiのアドレス。 "int array [5]"を宣言すると、プログラムは実際にコンピュータメモリB0、B1、...の全域に散在するintポインタP0、P1、...、P4と5 intサイズのメモリ場所の5つの隣接ボックスを実際に割り当てる。 ..パイの値はバイ

のアドレスであるB4

enter image description here

は、私が正しいか間違っている!! ??ありがとうございました!このように、それの

+6

いいえ、 'int * arr []'を持たない限り、配列は実際の整数を持ちます。 – chris

+2

+1の画像: –

+1

[comp.lang.c FAQ](http://www.c-faq.com/)のセクション6を読んでください。 –

答えて

7

アレイは、[...]メモリに実際に実際の値+それらのメモリボックスを含むメモリボックスのBiのアドレスをそれぞれ含むn個のポインタの配列である

いいえ。

int array[10];int *array = ...;と宣言された配列の両方について、array[0] == *(array+0) == *arrayが真実である可能性があります。完全に合理的な質問。ポインタptrの場合、式*ptrはポインタが指している値を取得すると言われています。したがって、同じ構文を配列で使用すると、逆参照するアドレスはどこにありますか?

ここでは秘密です:配列インデックス演算子([])は、CおよびC++の配列では機能しません。配列に適用すると、言語は暗黙的に配列を配列の最初の要素へのポインタに変換します。したがって、配列への追加または配列の逆参照は、ポインタの追加または参照解除と同じように動作します。

int array[10]; 

// These lines do exactly the same thing: 
int *ptr1 = &array[0]; // explicitly get address of first element 
int *ptr2 = array;  // implicitly get address of first element 

したがってアレイは、実際の各要素は、実際の値ではない値を含む他の位置へのポインタであるメモリ内の要素の連続集合です。配列が定義されているということは、暗黙的にポインタに変換されることが多いことを意味しています。実際に暗黙の変換がある場合はポインタがあるようです。

+0

"配列インデックス演算子([])は配列では機能しません。"もちろんそうです。それがそれのためのものです。しかし、演算子*はポインターの追加と同じです。 – EJP

+4

@EJPいいえ、C++仕様を読んでいれば、添字演算子は配列型の式ではなく "Tへのポインタ"型の式でしか動作しないことがわかります。配列上の添え字を使用する理由は、配列上でそれを使用すると、最初に配列をポインタに変換し、その後は実際には同じになるため、ポインタで使用する理由と同じです。 – bames53

+0

@EJPこれを見る別の方法は、次のようなコードでclangのASTダンプ機能を使用する場合です: 'int main(){int array [10];配列[0]; } 'の場合、ASTは左側に' ImplicitCastExpr 'というノードを持つ' ArraySubscriptExpr'というノードを表示します。 – bames53

0

思う:

array[n]は単に*(array + n)のためのシンタックスシュガーです。

いいえ、ポインタはありません。実際には、配列には連続メモリ範囲の値が含まれています。

+0

ええ、それは私が書いたものです、そして、私はそれを理解していますが、私の質問は、 "int array [n]"(またはそのような他のタイプの場合)のメモリ割り当ての場合に起こることです。 –

+1

'*'は参照解除を行うので、 'n'から* value *を取得します。もしあなたが書いたことが真実ならば、逆参照の余分なステップが必要になるでしょう。 (ただし、表記法からはっきりとわかるようにはありません)。 –

+1

あなたの写真の緑色の部分が見えますか?そこに直接値を書き込んでください。それは何が起こるかです。実際の割り当ては、ローカル変数であるか動的に割り当てられているかによって異なります。それぞれには独自の(実装固有の)ルールがありますが、配列固有ではありません。 –

2

アレイは仮想メモリに連続して格納されます。ただし、マップする物理メモリのアドレスは連続していても、連続していなくてもかまいません。

配列要素は、次の要素を指すポインタを格納しません。値のみが格納されます。大括弧([])で宣言

関連する問題