今回は《ポインタとポインタについて学ぼう》というテーマで記事をまとめます。
C言語における『鬼門』である「ポインタ」の中でも更に難しい要素である「ポインタのポインタ」ですが、これを習得できれば「ポインタ」の基礎がほぼほぼ習得できたことになります。しっかり学んでいきましょう!
ポインタの基本を習得していない方は、まずは下記の記事を参考に学習をしてみてください。
尚、現在執筆中のC言語入門記事は以下の人を対象としています。
- プログラミング未経験の人
- C言語プログラミングの学習をこれから始めたい人
- C言語プログラミングの学習を始めたばかりの人
ポインタのポインタについて学ぼう
ポインタのポインタとは
ポインタも1つの変数である為、ポインタ変数を参照するポインタ変数も存在します。それが「ポインタのポインタ」です(「ダブルポインタ」と呼ばれることもある)。
変数定義と使用方法
それでは、ポインタのポインタについて、変数定義と使用方法を解説していきたいと思います。
変数定義
変数定義は、通常のポインタ変数と大きく変わりません。当たり前と言えば当たり前なのですが、「ポインタのポインタ」なので、”*”が2つ付与されるところが注意点でしょうか。
基本的な書式は次のようになります。
変数の型** ポインタのポインタ変数名;
アドレス取得
アドレス取得についても、通常のポインタ変数と大きく変わりません。こちらも当たり前と言えば当たり前なのですが、「ポインタのポインタ変数」に代入できるアドレスは「ポインタ変数自身のアドレス」です。
書式は次のようになります。
/* ポインタのポインタ変数に、ポインタ変数のアドレスを代入 */ ポインタのポインタ変数名 = &ポインタ変数名;
変数の参照(参照先変数への値の代入・取得)
お次は、参照先変数へ値を代入したり、参照先変数から値を取得する方法について解説します。
今回扱う変数は「ポインタのポインタ」である為、参照先変数(=ポインタ変数)と参照先変数の参照先変数(=通常の変数)への値の代入・取得方法を解説します。
書式は次のようになります。
/* ポインタのポインタ変数が指すポインタ変数に、値(アドレス)を代入 */ *ポインタのポインタ変数名 = &通常の変数名; /* ポインタのポインタ変数が指すポインタ変数から、値(アドレス)を取得 */ ポインタ変数 = *ポインタのポインタ変数名;
/* ポインタのポインタ変数が指すポインタ変数が指す変数に、値を代入 */ **ポインタのポインタ変数名 = 値; /* ポインタのポインタ変数が指すポインタ変数が指す変数から、値を取得 */ 他の変数名 = **ポインタのポインタ変数名;
上記の通り、参照先変数(=ポインタ変数)を参照する場合は変数の前に”*”を付与し、参照先変数の参照先変数(=通常の変数)を参照する場合は変数の前に”**”を付与します。
これだけではよくわからない!という方が大半だと思うので、今回は参照イメージを用意しました。より想像しやすいように具体的なソースコードと絡めて解説したいと思います。
尚、今回のイメージにおけるメモリサイズは「32bitアプリケーションであること」を想定しています。32bitアプリケーションの意味が分からない方は、とりあえず無視してもらっても構いません(本質的に、今回のお話とは関係ない為)。
サンプル
それでは、サンプルを用意したので実行してみてください。
#include <stdio.h> void main() { int num1 = 10; int num2 = 20; int* pnum = NULL; int** ppnum = NULL; /* ポインタ変数pnumの参照先をnum1とする */ pnum = &num1; /* ポインタのポインタ変数ppnumの参照先をpnumとする */ ppnum = &pnum; /* 表示 */ printf( "num1 = %d\n", num1 ); printf( "num2 = %d\n", num2 ); printf( "pnum = %p\n", pnum ); printf( "*pnum = %d\n", *pnum ); printf( "**ppnum = %d\n", **ppnum ); printf( "\n" ); /* ppnumの参照先の参照先変数(num1)へ値の代入 */ **ppnum = 100; /* ppnumの参照先変数(pnum)の参照先を変更(num2に変更) */ *ppnum = &num2; /* pnumの参照先変数(num2)へ値の代入 */ *pnum = 200; /* 再表示 */ printf( "num1 = %d\n", num1 ); printf( "num2 = %d\n", num2 ); printf( "pnum = %p\n", pnum ); printf( "*pnum = %d\n", *pnum ); printf( "**ppnum = %d\n", **ppnum ); }
次回は「型変換」
今回で「ポインタの基礎」は一旦終了です。と言っても、次記事の内容でもポインタを使用します。
次記事の内容は「型変換」です。
「型変換」を習得すれば、よりバリエーションに富んだプログラムコードを書くことができます。
ご期待ください。