8

私はこの質問をSOでよく見ます。多分それほど多くの言葉ではありません...しかし、配列がポインタとどのように異なるかについて何度も混乱があります。それで、私はこれについていくつかのポイントをQ&Aするのに少し時間がかかると思いました。

このQ&Aの目的のために、32ビットシステムを想定し、以下が宣言されています。

char * ptr = "hello";
char arr[10] = "hello";
int iarr[10] = {0};

これが私がSOで見た混乱を推測する質問のリストです。新しいものを見つけたら、Q&Aのリストに追加します(他の人も気軽に、間違いを見つけたら訂正してください!)

  1. ポインタと配列は基本的に同じものではありませんか?
  2. フォローアップ:との両方*(ptr)*(arr)または同じことptr[0]arr[0]与えるのはなぜですか?
  3. どうして同じ値ですかarr&arr
  4. フォローアップ:なぜ私は異なる値の印刷を取得するのですarr+1&arr+1
4

1 に答える 1

21

1)ポインタは配列ではありません。配列はポインタではありません。それらは異なるので、そのように考えないでください。
どうすればこれを証明できますか?彼らが記憶の中でどのように見えるかを考えてください:

配列のarr長さは10文字です。「こんにちは」が含まれていますが、待ってください、それだけではありません!メッセージよりも長い静的に宣言された配列があるため、無料で大量のNULL文字('\0')がスローされます。また、名前arrが隣接する文字に概念的に付けられていることに注意してください(何も指していません)。 ここに画像の説明を入力してください

次に、ポインタがメモリ内でどのように見えるかを検討します。 ここに画像の説明を入力してください ここでは、読み取り専用メモリ内のどこかで文字配列を指していることに注意してください。

したがって、arrとは両方ともptr同じ方法で初期化されましたが、それぞれの内容/場所は実際には異なります。

これが重要なポイントです
。ptrは変数であり、任意のものを指すことができます。arrは定数であり、常にこの10文字のブロックを参照します。


2)[]は、アドレスで使用できる「加算および差分」演算子です。arr[0]それは言うことと同じ意味です*(arr+0)。そうです、これを行います:

printf("%c %c", *(arr+1), *(ptr+1));

「ee」の出力が表示されます。配列がポインタであるからではなく、配列の名前arrとポインタptrの両方がたまたまあなたにアドレスを与えるからです。

#2の要点:差分演算子*と加算および差分演算子[]は、それぞれポインターと配列に固有のものではありません。これらの演算子は単にアドレスを処理します。


3)私は非常に単純な答えを持っていません...それで私たちの文字配列を少し忘れて、説明のためにこの例を見てみましょう:

int b;   //this is integer type
&b;      //this is the address of the int b, right?

int c[]; //this is the array of ints
&c;      //this would be the address of the array, right?

だから、これはかなり理解できます:

*c;   //that's the first element in the array

そのコード行から何がわかりますか?私が服従する場合c、私はintを取得します。つまり、単なるcアドレスです。これは配列の先頭であるため、配列のアドレスであり、配列の最初の要素のアドレスでもあります。したがって、値の観点からは次のようになります。

c == &c;

4)ここで少し話題を外しましょう...この最後の質問は、アドレス演算の混乱の一部です。ある時点で、アドレスが単なる整数値であることを示唆するSOに関する質問を見ました...Cではアドレスはタイプの知識を持っていることを理解する必要があります。つまり、次のようになります。

iarr+1; //We added 1 to the address, so we moved 4 bytes
arr+1;  //we added 1 to the address, so we moved 1 byte

基本的に、sizeof(int)は4で、sizeof(char)は1です。したがって、「配列に1を追加する」ことは、見た目ほど単純ではありません。

では、質問に戻りましょう。なぜとはarr+1違うの&arr+1ですか?1つ目は1 * sizeof(char)アドレスに=1を追加し、2つ目はアドレスに1 * sizeof(arr)=10を追加します。

これが、両方とも「1を加算するだけ」であるにもかかわらず、異なる結果をもたらす理由です。

于 2012-10-01T15:35:10.843 に答える