10.ポインタ

10-14. 関数のポインタ

◇関数のポインタ

関数も変数と同様、アドレスを持ちます。
そこで今回の関数のポインタはその関数のアドレスをポイントしようというものです。

◇宣言の例

型 (*識別名)(引数の型);

ここで型と引数の型はポイントされる関数と一致しなければなりません。

例えば、ポイントされる関数が int func(char) の場合関数のポインタ宣言は

int (*識別名)(char);

となります。

◇実践サンプル
では早速サンプル。

void func(int);

int main()
{
    void (*P_func)(int); /* (1) */
    P_func = func;       /* (2) */
    (*P_func)(1);        /* (3) */
    return 0;
}

void func(int i)
{
    printf("%dが渡されました\n",i);
    return;
}

解説
(1)関数ポインタP_funcの宣言文です。
(2)関数funcのアドレスを関数ポインタP_funcに代入します。
(3)関数ポインタP_funcを介して関数funcを呼び出しています。

◇関数ポインタ-応用

次のプログラムはANDとORの演算をして表示するものです。

#include<stdio.h>

int and(int x,int y);
int or(int x,int y);

void main()
{
    int (*p_func[2])(int x,int y);
    int i,j,k;

    p_func[0] = and;
    p_func[1] = or;

    printf("x  y  AND  OR\n");
    for(i=0;i<2;i++){
        for(j=0;j<2;j++){
            printf("%d  %d  ",i,j);
            for(k=0;k<2;k++){
                printf(" %d  ",(*p_func[k])(i,j));
            }
            printf("\n");
        }
    }
}

int and(int x, int y)
{
    return x&&y;
}

int or(int x, int y)
{
    return x||y;
}

/* 結果
x  y  AND  OR
0  0   0   0
0  1   0   1
1  0   0   1
1  1   1   1
*/

ポイントの仕方を図示すると次のようになります。

p_op[4] int and(int x, int y)
+———+ +———————+
| p_op[0] |—–>| { return x && y } |
+———+ +———————+
| p_op[1] |–+
+———+ | int or(int x, int y)
| +———————+
+–>| { return x || y } |
+———————+

このようにポインタ配列と組み合わせることによって別の関数をfor文で連続的に呼び出すことができます。