C言語のダブルポインタ(ポインタのポインタ)を解説

ダブルポインタがポインタを指す様子

このページではダブルポインタ(ポインタのポインタ)について説明したいと思います。

ポインタについては下記の記事で解説していますので、まだ理解が不十分という方は是非見てみてください。

ポインタ解説ページのアイキャッチ徹底図解!C言語ポインタを初心者向けに分かりやすく解説

ダブルポインタとは

ダブルポインタとはポインタのアドレスを格納する変数です。

変数宣言は下記のように行います。

型 **ポインタ名;

ダブルポインタを用いたプログラム

ダブルポインタは、例えば下記のような使い方をしてみるとイメージつきやすいと思います。

ソースコード

main.c
#include <stdio.h>
#include <stdlib.h>

int main(void){

  int **dptr;
  int *ptr;
  int data;

  data = 123;

  ptr = &data;
  dptr = &ptr;

  printf("ptr = 0x%x\n", ptr);
  printf("*ptr = %d\n", *ptr);

  printf("dptr = 0x%x\n", dptr);
  printf("*dptr = 0x%x\n", *dptr);
  printf("**dptr = %d\n", **dptr);

  return 0;
}

実行結果は私の場合は下記のようになりました。「私の場合は」とわざわざ言ったのは、PCや実行したタイミングによって下線部は値が異なるからです。

ptr = 0xefab3af4
*ptr = 123
dptr = 0xefab3af8
*dptr = 0xefab3af4
**dptr = 123

注目点は、ptr と *dptr が同じ値のアドレスになっていることです。

data と ptr と dptr の関係を図示すると下のようになります。

ダブルポインタがポインタを指す様子

変数は宣言することでメモリ空間上に値を格納するための領域が確保されます。これは int 型や double 型の変数だけでなく実はポインタも同じでメモリ空間上にその変数用のメモリ領域が確保されます。メモリ空間上に存在するものは、それがどこに存在するかをアドレスで管理されていますので、ポインタ自体もポインタでそのアドレスを指すことが可能です。そのポインタを指すポインタがダブルポインタ(ポインタのポインタ)です。

プログラムの動き

上のプログラムの動きを見ていきましょう。

まず下記の変数宣言により、3つの変数がメモリ上に作成されます。

  int **dptr;
  int *ptr;
  int data;

図で表すと下のようになります。

メモリ空間上に変数が配置される様子

次に下記により、data に値が格納されます。

  data = 123;

図で表すと下のようになります。

data変数に値が格納される様子

続いて、下記によって ptr に data 変数のアドレスが格納されます。つまり、ptr は data 変数を指すことになります。

  ptr = &data;

図で表すと下のようになります。

ポインタが変数を指す様子

ですので、ptr の値を表示すると、data のアドレス(&data)が表示されることになります。

ptr = 0xefab3af4

一方、*ptr は ptr が指す先に格納されている値となりますので、下記では ptr が指す data の値である “123” が表示されます。

*ptr = 123

続いて dptr を見ていきましょう。ptr がポインタであるのに対し、dptr はダブルポインタであり、ポインタを指すポインタです。

この dptr には下記によって ptr のアドレスが格納されます。つまり dptr は ptr を指すことになります。

  dptr = &ptr;

メモリ空間を図で表すと下のようになります。

ダブルポインタがポインタを指す様子

これによりポインタ変数のアドレスを他のポインタが指すことになります。このポインタ変数のアドレスを指すポインタが、ダブルポインタ(ポインタのポインタ)です。

dptr は ptr を指していますので、dptr が指す先に格納されている値である *dptr と ptr は同じ値となります。

ptr = 0xefab3af4
*dptr = 0xefab3af4

つまり、dptr が指す先に格納されている値である *dptr はアドレスであり ptr と同じものになります。したがって、*dptr が指す先を **dptr で参照することが可能であり、**dptr は *ptr と同じ値、つまり data の値となります。

ダブルポインタから変数の値にアクセスする様子

スポンサーリンク

トリプルポインタ

同様の考え方で、ダブルポインタを指すトリプルポインタを使用することも可能です。

main.c
#include <stdio.h>
#include <stdlib.h>

int main(void){

  int ***tptr;
  int **dptr;
  int *ptr;
  int data;

  data = 123;

  ptr = &data;
  dptr = &ptr;
  tptr = &dptr;

  printf("ptr = 0x%x\n", ptr);
  printf("*ptr = %d\n", *ptr);

  printf("dptr = 0x%x\n", dptr);
  printf("*dptr = 0x%x\n", *dptr);
  printf("**dptr = %d\n", **dptr);

  printf("tptr = 0x%x\n", tptr);
  printf("*tptr = 0x%x\n", *tptr);
  printf("**tptr = 0x%x\n", **tptr);
  printf("***tptr = %d\n", ***tptr);

  return 0;
}

まとめ

最後に説明した内容まとめます。

  • ダブルポインタ(ポインタのポインタ)はポインタ変数のメモリ空間上のアドレスを指すポインタです
  • 変数宣言では「**ptr」のように*を2つ重ねて記述します
  • ダブルポインタだけでなくトリプルポインタなどのように何重にもポインタを指すポインタを定義していくことが可能です

 

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です