C言語入門(16) ポインターはわかったけど参照(&)って?

Posted: 2012年11月21日

これまでの解説でポインター(*)について書いてきましたが
参照(&)とは何か

参照では、自身のメモリーアドレスを返します。

int nResult = *(&var);

この場合は、自身のアドレスを取得後
nResultにそのアドレスの値を代入します。
つまり

int nResult = var;

と同様
「*と&は逆の操作ができる」と覚えることを薦めます。

実際にはどのような使い方をしているのでしょうか?

プログラムプログラム:

#include <stdio.h>

BOOL GetCount(int *pCount)
{
    if (pCount == NULL) {
        return FALSE;
    }
    // インクリメント
    *pCount++;

    return TRUE;
}

int main(void)
{
    int nCount = 0;

    // カウント値の取得
    GetCount(&nCount);
}

解説解説:

関数GetCountは、引き数値がIN/OUTで構成されているため
結果を取得するため引数がポインター変数になっています。

素直にポインター変数を用意する(動的に領域を確保)ことはせずに
通常の変数(nCount)のアドレスを渡すことでGetCountの要件を満たしています。

この方法を用いることでメモリーの領域を解放する必要がないため(動的に確保していないから)
安全に処理を行えます。

そのほかにも異なる参照の使用方法があります。
こちらは、C言語では、できずC++でしかできませんが
引数を参照で受け取ることです。

プログラムプログラム:

#include <stdio.h>

BOOL GetCount(int &nCount)
{
    // インクリメント
    nCount++;

    return TRUE;
}

int main(void)
{
    int nCount = 0;

    // カウント値の取得
    GetCount(nCount);
}

解説解説:

ポインターで使用した場合よりも
シンプルかつ、まるでポインターを使用していない通常の引数のように扱えます。

呼び側は、特に変更に必要がなく
関数の定義で切り替えることが可能です。

呼び出し側では参照設定しているかどうかはわからないため
変更するつもりなかったが変更されていてバグになる場合などがあるため
一定のポリシーを持ち実装する必要があります。

私が持っているポリシーは、

タイプ 説明
変更が必要ない(IN) const int ○○ 定数扱いにする
変更の必要あり(IN/OUT) int &○○ 参照設定
戻り値のみ(OUT) int &○○ 参照設定
継承クラス class *○○ ポインター変数
配列 int *○○ ポインター変数

あくまで、個人で開発するときやコーディングルールが決まっていない場合のみ適用しています。
コーディングルールも更新しないと忘れ去られているため更新したほうがいいのかな
プロジェクトでどのバージョンのコーディングルールを採用するとか

練習練習:

  1. 参照、ポインターのメリット/デメリットを考慮して独自のポリシーを考えてみる
カテゴリー: プログラム, 入門 | タグ: , , | コメント無し »

コメント