「この順で」というところを赤字にしましたがここが大事なのです。 バラバラの所に確保されるのではなく、「この順に」固まって確保されるのです。 仮に、a[0]が100番地に確保されたとします。int型が2バイトだとすると a[1]は102番地、a[2]は104番地に確保されます。そこで、int型をさす ポインタをptrとすると、int a[4];とするとa[0], a[1], a[2], a[3]が メモリ中のどこかに、この順で確保されます。
どうです?わかりました?多分上の青字の3行目までは理解できると思います。 問題は4行目以降です。&a[0]は100番地を表しているのにどうして &a[0] + 1 が102番地を表すの?はい、それはCの約束だから仕方がないのです。 つまり、&a[0] + 1 はa[0]がint型であるため、その次の要素(a[1])のアドレス を表しているのです。最初に書いた「この順に」という意味がここにあるのです。 そしてさらに驚くべきことに 配列名[0]のアドレスは、 配列名で表すことができるのです。従って、a[0]のアドレス(&a[0])は a なのです。a[0] = 15; a[1] = 20; a[2] = 25; a[3] = 10;と各要素に代入 ptr = &a[0]; ptrはa[0]のアドレス(100番地)が代入された・・・当たり前! *ptr a[0]の中身すなわち15・・・これも当たり前! &a[0] + 1 a[1]のアドレスすなわち102番地 ・・・エエエエッ??? ptr + 1 上と同じ &a[0] と a は同じ ・・・・ううううう
どうです。この位例を出せば何となくわかってきたのではないでしょうか。 実際に、本当にそうなのかプログラムを作ってみましょう。&a[0] + 2 は a[2]のアドレスすなわち &a[2]と同じ(104番地) *(&a[0] + 2) は a[2]の内容すなわち 25 ptr + 2 は a[2]のアドレスすなわち &a[2]と同じ *(ptr + 2)は a[2]の内容すなわち 25 &a[0] は a[0] のアドレスで この値は、ptr に代入されている a は a[0]のアドレスを表すのでptrと同じ
配列を、宣言の時に一度に初期化してもよいです。
static int a[]={15,20,25,10};
どうです。わかりました?
さて、++という演算子がありました。i++;とすると i = i + 1;という意味でしたね。ポインタについても これができます。ポインタは変数だからです。 しかし、配列名に対してはこれはできません。 int a[4];においてaは&a[0]を表していますが 変数ではありません。定数です。また、配列名 でaを使ったなら、普通の変数としてaは使えません。 さて、今回の最も重要なことは配列名は、その配列の 先頭の要素のアドレスを表すということでした。 ポインタについては、まだまだ重要なことが山のようにあります。 いっぺんにやると、頭が混乱しますので少しずつ、 少しずつやっていきましょう。
Update Nov/12/1996 By Y.Kumei