C言語入門(14) ポインターはいつ使うべきなのか(3)

Posted: 2012年09月04日

前回は何も書きませんでしたが、今回も続きものです。
続きということでおらさい

前回と前々回は、

  • 配列のアクセス
  • 関数の引数
  • 関数ポインタ
  • 可変配列

を行いました。

では、さっさと見て行きましょう!!

ポインターポインター(ダブルポインター、トリプルポインター)

ポインタ変数のメモリー位置をポインタ変数に保持できます。
そのため、ダブル、トリプルが上限ではなくメモリーの許す限りポインターポインターを作成できます。

 int **ppnCount; // ダブル
 int ***pppnCount; // トリプル

ポインターポインターは何に役立つのでしょうか
決して言いたいだけじゃないです!!

プログラムプログラム:

#include <stdlib.h>

BOOL GetUserName(char **ppszName, int *pnCount)
{
    *pnCount = sizeof("Allen Walker") / sizeof(char);
    char *pszName = (char *) malloc(*pnCount);

    // 配列にデータをコピー
    strncpy(*ppszName, "Allen Walker", *pnCount);

    return TRUE;
}

int main(void)
{
    char *pszName;
    int nDataSize;

    // ユーザ名を取得
    GetUserName(&pszName, nDataSize);

    free(pszName);
}

解説解説:

あまり推奨される形ではありませんが
GetUserNameでは、ユーザ名のサイズの領域を確保し、その配列と、サイズを返却します。
使用後は、freeをする必要があります。
何が推奨されないかは、
領域を確保と解放する場所が離れているため
修正した際に解放漏れをする可能性があります。

本題に戻りまして
このプログラムでダブルポインタの使い方は、
GetUserNameでポインター変数を引数でもらい
その変数に動的メモリー領域のポインターを代入します。
動的メモリー領域は、freeをするまで解放されませんが
GetUserNameのpszNameは解放されるため呼び出し元に渡すためにこのような手段をとっています。

ほかにも身近な例でかつ、他の使用方法

プログラムプログラム:

#include <stdio.h>

int main(int argc, char **argv)
{
    int nIndex = 0;
    for (nIndex = 0; nIndex < argc; nIndex++)
    {
        puts(*(argv + nIndex));
    }
}

解説解説:

シンプルでかつ、一番わかり易い例かと思われます。
main関数は、argc 引数の数 argv 引数の文字列
文字列は、charの配列のため
argvはcharの2次配列が設定されている状態と同様です

今回の使い方では、
多次元配列ぶんのポインタポインタで引数に渡すことが可能です。
ただ、分かりづらいため構造体などにしてダブルポインターまでが実用範囲内と思っています。

カテゴリー: プログラム, 入門 | タグ: , | コメント無し »

コメント