配列とポインタ

言語学習者がまず混乱するのは配列とポインタの関係ですよね。この二つは全く別のものと思いきや、実は同じようなもので、でもやっぱり違うんです。
配列は int a[10]; のように宣言し、ポインタは int *p; のように宣言します。ところが、配列 a を使って *(a+5) と書くこともできますし、ポインタ p を使って p[5] と書くこともできます。配列とポインタの違いは [ ] と書くか * と書くかという見た目の違いではありません。ではどこが違うかというと、ポインタ p は p++; などの演算ができますが、配列 a で a++; などと書くとエラーになります。つまりポインタはアドレス可変、配列はアドレス固定なのです。

  • 配列はアドレス定数 (宣言時に領域確保されたメモリアドレスを指す)
  • ポインタはアドレス変数 (宣言時に領域確保はされない)

と考えればよいかなと思います。配列は領域確保されたメモリを指すものなのでアドレスを変えることができないのですね。
ちなみに、


int a[11];
int *p;
p = &a[5];
とすると p は p[-5]からp[5]までの11の値を扱えます。配列でマイナスの添え字を使いたい場合はこのような書き方ができます。

#include <stdio.h>

int main(void)
{
int a[11] = {-55,-44,-33,-22,-11,0,11,22,33,44,55};
int *p;
int i;

p=&a[5];

for(i=-5; i<=5; i++){
printf("p[%2d] = %3d\n", i, p[i] );
}

return 0;
}