関数ポインタ

C言語では,変数だけでなく関数を指すためのポインタも存在する.
変数のポインタですら抵抗はあると思うので,ましてや関数のポインタなど..., と思うかも知れないが,関数の引数に関数を渡すなど便利な場合があるので,覚えておこう.

どんな場合に便利かというと,

などである. 関数ポインタのみ,関数ポインタと引数の組み合わせなど,様々な呼び出し方が可能である.

サンプルソースコード

#include <stdio.h>

/* pf の引数は,「戻り値void,int1個の引数をとる関数」へのポインタと,「整数」 */
void call_func(void (*pf)(int), int x)
{
    pf(x);    /* 関数ポインタ pf を使った関数呼び出し */
}

void func_A(int n)
{
    printf("by func_A, n^2 = %d\n", n*n);
}

void func_B(int n)
{
    printf("by func_B, n^3 = %d\n", n*n*n);
}

int main()
{
    /* 例1:関数を指すポインタ変数 */
    void (*p)(int);     /* ポインタ変数を宣言 */

    p = func_A;
    printf("p = 0x%p, ", p);  /* pointer の指すアドレスを表示 */
    p(2);                   /* ポインタを使って関数呼び出し */

    p = func_B;
    printf("p = 0x%p, ", p);
    p(2);


    /* 例2:関数のアドレスを別の関数の引数として渡す. */
    /* 同じデータに対して,違う処理をしたい場合に使える. */
    int n = 10;
    call_func(func_A, n);   /* 関数名 func_A を引数として呼び出し. */
    call_func(func_B, n);   /* 関数名 func_B を引数として呼び出し. */

    return 0;
}
実行例(bcc32c):
p = 0x00401210, in func_A, n^2 = 4
p = 0x00401240, in func_B, n^3 = 8
by func_A, n^2 = 100
by func_B, n^3 = 1000

実行例(Microsoft VisualC++ 64bit):
p = 0x00007FF6C8571020, in func_A, n^2 = 4
p = 0x00007FF6C8571050, in func_B, n^3 = 8
by func_A, n^2 = 100
by func_B, n^3 = 1000

関数ポインタは,その宣言がややわかりにくいが,慣れてしまえば非常に便利である.