Тип указателя функции точно так же, как и объявление функции, но с именем «(*)» вместо имени функции. Таким образом, указатель на:
int foo( int )
будет:
int (*)( int )
Чтобы назвать экземпляр этого типа, введите имя внутри (*), после звезды, поэтому:
int (*foo_ptr)( int )
объявляет переменную с именем foo_ptr, которая указывает на функцию этого типа.
Массивы следуют нормальному синтаксису C, чтобы скобки располагались рядом с идентификатором переменной, поэтому:
int (*foo_ptr_array[2])( int )
объявляет переменную с именем foo_ptr_array, которая представляет собой массив из 2 указателей на функции.
Синтаксис может стать довольно грязным, поэтому часто бывает проще сделать typedef указателю на функцию а затем объявить массив из них:
typedef int (*foo_ptr_t)( int );
foo_ptr_t foo_ptr_array[2];
В любом примере вы можете делать такие вещи, как:
int f1( int );
int f2( int );
foo_ptr_array[0] = f1;
foo_ptr_array[1] = f2;
foo_ptr_array[0]( 1 );
Наконец, вы можете динамически выделять массив с любым из:
int (**a1)( int ) = calloc( 2, sizeof( int (*)( int ) ) );
foo_ptr_t * a2 = calloc( 2, sizeof( foo_ptr_t ) );
Обратите внимание на добавочный * в первой строке, чтобы объявить a1 как указатель на указатель функции.