「ポインタの基礎」

配列とポインタ

C言語の配列とポインタは似ている面がある。
例えば、以下のサンプルコードでは 同じ配列の要素を参照するために4種類の方法を使っている。

最初の"itab[i]"は通常の配列の参照を行なう記述法である。
2つ目の"pi[i]"はポインタ変数を用いたもので、"pi"はポインタ変数であり、 配列変数ではないが、ポインタ変数を配列変数と同じように扱っている。
3つ目の"*(pi + i)"はポインタ変数にオフセットをつけて値を参照する方法で あり、ポインタ変数が指すアドレスから"i"番目後方にあるデータの値を参照 する。
4つ目の"*(itab + i)"は、今度は逆に配列変数をポインタ変数的に扱っている 方法で、"itab"が配列の先頭のアドレスを指しており、その"i"番目後ろの要 素のアドレス、すなわち"i"番目の要素の値を参照する。

#include <stdio.h>

int
main(void)
{
    int i;
    int itab[5] = {1, 2, 3, 5, 8};
    int *pi;

    pi = &itab[0];

    for (i = 0; i < 5; i++)
	printf("itab[%d]=%d  pi[%d]=%d  *(pi+%d)=%d  *(itab+%d)=%d\n",
	       i, itab[i], i, pi[i], i, *(pi+i), i, *(itab+i));

    return 0;
}

実行結果は以下のようになる。 どの方法を用いても同じ値が参照される。

itab[0]=1  pi[0]=1  *(pi+0)=1  *(itab+0)=1
itab[1]=2  pi[1]=2  *(pi+1)=2  *(itab+1)=2
itab[2]=3  pi[2]=3  *(pi+2)=3  *(itab+2)=3
itab[3]=5  pi[3]=5  *(pi+3)=5  *(itab+3)=5
itab[4]=8  pi[4]=8  *(pi+4)=8  *(itab+4)=8

以下の図は上記サンプルプログラムにおいての、ポインタと配列の関係を 示したものである。
ポインタ変数 pi に配列の先頭アドレス(つまり、&itab[0])を代入した後は、 ポインタ変数を配列のように使うことも出来れば、配列を使ってポインタのよ うに使うことも出来る。

ポインタと配列の関係その1

ここで、もしポインタ変数の値を1だけ大きい値に変更した場合、 ポインタ変数が指す配列の要素は配列の先頭ではなく、隣の要素を指すようになる。 つまり、配列中のある特定の要素を直接指し示すことができる。
(そのため、同じ配列要素を参照するためには、ポインタ変数に対するオフセッ ト値(あるいは添字の数)をそれぞれ1つずつ小さくなる必要がある)

ポインタと配列の関係その2

このようにポインタと配列は同じように使うことが可能である場合もあるが、 全く同じものではない。 例えば以下の例で、ポインタ変数は値の書き換えが出来るが、配列変数は書き 換えが出来ない。

int itab[5] = {1, 2, 3, 5, 8};
int *pi = &itab[0];

pi = pi + 1;           /* OK (ポインタ変数は書き換えられる) */
itab = itab + 1;       /* エラー (配列変数は書き換えができない) */


文責:大津