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を加算するだけ」であるにもかかわらず、異なる結果をもたらす理由です。