関数の引数に、関数ポインタを渡すことによって、高階関数のようなことができる。
次のプログラムは、整数の配列にフィルタをかけてその結果を表示する。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)
でいいということ。