関数ポインタ

関数ポインタは、関数のエントリポイントのアドレスを保持する変数。
コンパイラは、プログラムをコンパイルするときに関数のエントリポイントを作成する。エントリポイントはアドレスなので、それを指すポインタ変数を持つことが可能だ。それが関数ポインタ。

関数ポインタを宣言するには、その関数の戻り値の型のポインタとして、関数に引数があればそれも続けて宣言する。

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
int (*p) (int x, int y);
int (*p) (int x, int y);
int (*p) (int x, int y);

優先順位の規則のため、*p はカッコで囲む必要がある。

関数のアドレスを関数ポインタに代入するには、関数名をカッコを付けずに指定する。例えば、次のような関数 sum() があるとすると:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
int sum(int a, int b);
int sum(int a, int b);
int sum(int a, int b);

次のように代入する。

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
p = sum;
p = sum;
p = sum;

代入した関数を呼び出すには:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
result = (*p) (10, 20);
result = (*p) (10, 20);
result = (*p) (10, 20);

呼び出し時にも *p をカッコで囲む必要がある。

戻り値の型と引数の数、型が同じであれば、関数ポインタを配列にすることもできる。

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
int (*p)[4] (int x, int y);
int (*p)[4] (int x, int y);
int (*p)[4] (int x, int y);

次のプログラムは、ユーザに2つの整数を入力させ、次に行いたい演算の番号を入力させる。そしてその結果を表示する。
ユーザの入力した番号から演算を選ぶ部分で関数ポインタの配列を使っている。

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
#include
int sum(int a, int b);
int subtract(int a, int b);
int mul(int a, int b);
int dev(int a, int b);
int (*p[4]) (int x, int y);
int main(void)
{
int result;
int i, j, op;
p[0] = sum; /* Get address of sum() */
p[1] = subtract; /* Get address of subtract() */
p[2] = mul; /* Get address of mul() */
p[3] = dev; /* Get address of dev() */
printf("Input 2 numbers:\n");
scanf("%d%d", &i, &j);
printf("0: sum, 1: subtract, 2: mul, 3: dev\n");
do {
printf("Input number of operation:\n");
scanf("%d", &op);
} while ((op < 0) || (3 < op));
result = (*p[op]) (i, j);
printf("%d\n", result);
return 0;
}
int sum(int a, int b)
{
return a + b;
}
int subtract(int a, int b)
{
return a - b;
}
int mul(int a, int b)
{
return a * b;
}
int dev(int a, int b)
{
if (b) {
return a / b;
} else {
return 0;
}
}
#include int sum(int a, int b); int subtract(int a, int b); int mul(int a, int b); int dev(int a, int b); int (*p[4]) (int x, int y); int main(void) { int result; int i, j, op; p[0] = sum; /* Get address of sum() */ p[1] = subtract; /* Get address of subtract() */ p[2] = mul; /* Get address of mul() */ p[3] = dev; /* Get address of dev() */ printf("Input 2 numbers:\n"); scanf("%d%d", &i, &j); printf("0: sum, 1: subtract, 2: mul, 3: dev\n"); do { printf("Input number of operation:\n"); scanf("%d", &op); } while ((op < 0) || (3 < op)); result = (*p[op]) (i, j); printf("%d\n", result); return 0; } int sum(int a, int b) { return a + b; } int subtract(int a, int b) { return a - b; } int mul(int a, int b) { return a * b; } int dev(int a, int b) { if (b) { return a / b; } else { return 0; } }
#include

int sum(int a, int b);
int subtract(int a, int b);
int mul(int a, int b);
int dev(int a, int b);

int (*p[4]) (int x, int y);

int main(void)
{
    int result;
    int i, j, op;

    p[0] = sum; /* Get address of sum() */
    p[1] = subtract; /* Get address of subtract() */
    p[2] = mul; /* Get address of mul() */
    p[3] = dev; /* Get address of dev() */

    printf("Input 2 numbers:\n");
    scanf("%d%d", &i, &j);
    printf("0: sum, 1: subtract, 2: mul, 3: dev\n");
    do {
        printf("Input number of operation:\n");
        scanf("%d", &op);
    } while ((op < 0) || (3 < op));
    result = (*p[op]) (i, j);
    printf("%d\n", result);
    return 0;
}

int sum(int a, int b)
{
    return a + b;
}

int subtract(int a, int b)
{
    return a - b;
}

int mul(int a, int b)
{
    return a * b;
}

int dev(int a, int b)
{
    if (b) {
         return a / b;
    } else {
        return 0;
    }
}
takatoh@nightschool $ ./sample_12_6
Input 2 numbers:
57
24
0: sum, 1: subtract, 2: mul, 3: dev
Input number of operation:
2
1368

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です

このサイトはスパムを低減するために Akismet を使っています。コメントデータの処理方法の詳細はこちらをご覧ください