10.ポインタ

10-10. ポインタのポインタ

◇ポインタのポインタ

前回のプログラムでは、

main()
{
    int matrix[2][3]={{1,2,3},{4,5,6}};
        int **point;
        point=matrix;
    printf("matrix[0][0] = %d\n",**point        );
    printf("matrix[0][1] = %d\n",*(*point+1)    );
    printf("matrix[0][2] = %d\n",*(*point+2)    );
    printf("matrix[1][0] = %d\n",**(point+1)    );
    printf("matrix[1][1] = %d\n",*(*(point+1)+1));
    printf("matrix[1][2] = %d\n",*(*(point+1)+2));
}

コンパイル時にポインタへの代入に警告が出てきて実行するとページ違反で強制終了しました。

なぜ、このようなことになったのでしょう。というところから始まります。
因みにプログラム中に出ている **point は何でしょう?

これがポインタのポインタです。

そして次の行の代入は間違いです。
2重ポインタ(ここでは**pointのことをそう呼ぶことにします)はポインタを指し示すポインタを意味します。

それでは、代入するものは?

次の例を見てみましょう。

#include<stdio.h>

main()
{
        int i=10;
        int *p;
        int **point;

        p=&i;
        point=&p; /* ポインタpのアドレスを代入 */

        printf("      i = %d\n",i);
        printf("     *p = %d\n",*p);
        printf("**point = %d\n",**point);
        printf("     &i = %p\n",&i);
        printf("      p = %p\n",p);
        printf(" *point = %p\n",*point);
        printf("     &p = %p\n",&p);
        printf("  point = %p\n",point);
        printf(" &point = %p\n",&point);
}

/* 結果
      i = 10
     *p = 10
**point = 10
     &i = 0064FE00
      p = 0064FE00
 *point = 0064FE00
     &p = 0064FDFC
  point = 0064FDFC
 &point = 0064FDF8

*/

2重ポインタはポインタを指し示すためにあるので代入する値はポインタpのアドレスになります。

また、上の結果を表にしてみます。

メモリ番地 変数名 値
64FE00番地 i 10(10進)
64FDFC番地 p 64FE00(16進)
64FDF8番地 point 64FDFC(16進)

プログラム上で代入した通り
pointの値=pのアドレス
pの値=iのアドレス

になっています。ここでそれぞれ間接アクセスすると

|————|
0064FE00 i |10(10進) | i,*p,**point
|————|
0064FDFC p |64FE00(16進)| &i,p,*point
|————|
0064FDF8 point|64FDFC(16進)| &p,point
|————|

**point:

+<point>-+ +<p>—–+ +<i>—–+
| 64FDFC |–>| 64FE00 |–>| 10 |
+——–+ +——–+ +——–+

*point
+<point>-+ +<p>—–+
| 64FDFC |–>| 64FE00 |
+——–+ +——–+

*p
+<p>—–+ +<i>—–+
| 64FE00 |–>| 10 |
+——–+ +——–+

こんな感じになります。