関数の引数に、関数ポインタを渡すことによって、高階関数のようなことができる。
次のプログラムは、整数の配列にフィルタをかけてその結果を表示する。Filter() 関数は奇数だけを残すために Odd()、偶数だけを残すために Even() をそれぞれ受け取ることで、ひとつの関数で 2 種類のフィルタとして動作している。
#include
#define MAX 10
int Odd(int val);
int Even(int val);
int Filter(int (*func)(int), int items[], int results[], int n);
int main(void)
{
int items[MAX] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
int odds[MAX];
int evens[MAX];
int i, n;
printf("before: ");
for (i = 0; i < MAX; i++) {
printf("%d ", items[i]);
}
printf("\n");
n = Filter(Odd, items, odds, MAX);
printf("odds: ");
for (i = 0; i < n; i++) {
printf("%d ", odds[i]);
}
printf("\n");
n = Filter(Even, items, evens, MAX);
printf("evens: ");
for (i = 0; i < n; i++) {
printf("%d ", evens[i]);
}
printf("\n");
return 0;
}
int Odd(int val)
{
if (val & 1) {
return 1;
} else {
return 0;
}
}
int Even(int val)
{
if (!(val & 1)) {
return 1;
} else {
return 0;
}
}
int Filter(int (*func)(int), int items[], int results[], int n)
{
int i, j = 0;
for (i = 0; i < n; i++) {
if ((*func)(items[i])) {
results[j++] = items[i];
}
}
return j;
}
takatoh@nightschool $ gcc -Wall filter.c -o filter takatoh@nightschool $ ./filter before: 1 2 3 4 5 6 7 8 9 10 odds: 1 3 5 7 9 evens: 2 4 6 8 10
ところで、関数ポインタの型は引数名は書かなくてもいいんだな。つまり、
int (*func)(int val)
じゃなくて
int (*func)(int)
でいいということ。