PR

 今回は,配列とポインタの関係について説明します。C言語では,配列をポインタで扱うとスッキリしたプログラムが書けるということを実感してもらう――これが連載第8回の目標です。配列とポインタは,その関係が密接なため,「なんやこう,ごっちゃになるねん」というわかりにくさがあります。でも,理解できれば,コンピュータやプログラムがずっと身近なものに感じられるようになるはずです。今回の連載でじっくり解説しますので,どうぞゆっくり理解してください。

 今回は,理解を進めるためのキーワードをいくつか紹介しながら解説していきます。最初のキーワードは「配列はメモリー上に連続して確保される」と「ポインタも変数だから演算できる」です。この二つから解説を始めていきます。

配列にポインタでアクセスする

 配列については本連載の5回目で解説しました。みなさん,覚えていらっしゃいますか。おさらいの意味も込めてリスト1のプログラムをみていきましょう。

リスト1●配列を利用したプログラムの例
リスト1●配列を利用したプログラムの例
[画像のクリックで拡大表示]

 int型の値を五つ記憶できる配列tensuを定義して,92,70,94,85,100という値で初期化しました(リスト1の(1))。そしてfor文によるループの中で,tensu[0]からtensu[4]までの値とメモリー上のアドレスをprintf関数で出力します(2)。C言語では配列の添え字は0から始まるので,int tensu[5]と宣言するとint[0]からint[4]までの五つ要素を持つ配列が作成されるのでした。

 実行結果は図1のようになります*1。アドレスは16進数で表示されていますが,int型の配列なのでアドレスが4バイトずつ変化していることがわかります。int型の変数を入れる箱が,あるアドレスを起点として5個つながっているイメージですね。

図1●リスト1の実行結果
図1●リスト1の実行結果

 この配列に今度は,ポインタを使ってアクセスしてみましょう(リスト2)。リスト2の(3)にある「int *p;」でint型へのポインタpを定義し,(4)の「p=&tensu[0];」で配列の先頭要素のアドレスをポインタpに代入しています。

#include <stdio.h>

int main()
{
    int tensu[5] = {92,70,94,85,100};
    int i;
    int *p; ―――――――――――――――――――――(3)

    p=&tensu[0]; ――――――――――――――――――(4)
    for (i = 0; i < 5; i++) {
        printf("tensu[%d]の値は%d\tアドレスは%pです\n",
i,*(p+i),p+i); ―――――――――――――――――――(5)
    }
    return(0);
}
リスト2●配列にポインタでアクセスする

 リスト1では配列の添え字に使っていたiを,ポインタpに足すことで各要素のアドレスを求めています。(5)の「p+i」の部分です*2。実行結果は図2です。表示された値もアドレスも図1と同じですね。

図2●リスト2の実行結果
図2●リスト2の実行結果