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

Posted: 2012年08月28日

前回の続きということでおらさい

前回は、

  • 配列のアクセス
  • 関数の引数

を行いました。

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

関数ポインタ

関数ポインターとは何か?
関数もメモリー上に存在するため
ポインター位置を記憶することで、その関数を呼び出すことが可能になります。

しかし、関数の呼び出しなんてそのようなことを行わなくても
呼び出すことができます。
なんの利点があるのでしょうか

それは、特定の関数を呼び出さない自由度の高いプログラムにするために使用します。
この機能を使用している関数は、qsortです。

 void qsort(void *base, size_t num, size_t size,
            int (*compare)(const void*, const void*))
 base    配列
 num     配列要素数
 size    要素サイズ(byte)
 compare 比較関数ポインター

qsortは、compareという関数ポインターを受け付けます。
これは、数値なら数値の比較処理、文字列なら文字列の比較処理、その他の型はそれぞれの比較処理が存在するため
qsortでは、比較処理を引数で受け取りその関数を呼び出しソート処理を行います。

プログラムプログラム:

#include <stdlib.h>

//
// 比較関数
//
int compare2int(const void *a, const void *b)
{
    return *(int*)a - *(int*)b;
}

int main(void)
{
    int arySrcData[] = {5, 3, 54, 1, 4};

    // ソートを行う
    qsort(arySrcData, sizeof(arySrcData) / sizeof(int), sizeof(int), compare2int);
}

解説解説:

qsort関数でソート処理が行われますが、compare2int関数がqsortの要求している仕様に一致しなければ正しく動作しません。
qsortは、以下の戻り値を要求しています。

戻り値 意味
< 0 第二引数(b)のほうが大きい -1
0 等しい 0
> 0 第一引数(a)のほうが大きい 1

compare2intでは、a-bを行なっています。

bが大きい場合 0よりも小さい値
bが小さい場合 0よりも大きい値

になります。

動的メモリー領域(ヒープ領域)

動的メモリー領域とはなにか!
通常配列は、固定サイズのみ宣言が可能でしたが
この機能を用いることで必要なサイズの配列サイズを取得することが可能です。

ポインターが動的メモリー領域を作成するわけではありませんが
動的メモリー領域は、ポインターで取得するため
今回の話題に含めております。

プログラムプログラム:

#include <stdlib.h>

int main(void)
{
    int ndataSize = 5;
    // 領域を確保
    int *parySrcData = (int *) malloc(ndataSize);
    if (parySrcData == NULL) {
        return -1;
    }

    // 配列に対する処理

    // 確保した領域を破棄
    if (parySrcData != NULL) {
        free(parySrcData);
        parySrcData = NULL;
    }
}

解説解説:

動的メモリーは、確保した場合、破棄する必要があります。
破棄しない場合は、無駄にメモリーを使用し続けることになります。
これは、プログラムが実行中のみであり、処理が終了した場合は、破棄されます。
処理が短いプログラムの場合は、問題にはならないですが
処理が長い、または、ずっと実行し続けるプログラムは、注目されます。
しかし、処理が短いから気にしないという事はせずに
破棄することをお勧めいたします。

mallocで動的メモリを確保します。
引数は、確保するサイズ(byte)を指定します。

確保した領域は、free関数を用いて解放いたします。
二度解放するとまだ問題になるため
解放した場合は、NULLを設定してそれ以降
解放しないようにするようにしたほうがいいでしょう

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

コメント