Процедурное программирование на языке С. Часть 2. Указатели на объекты. Многоуровневая адресация: Методические указания к лабораторным работам по курсам «Алгоритмические языки и программирование» и «Процедурное программирование», страница 2

Синтаксическая форма объявления указателя на функцию имеет вид:

<спецификация типа>  (*func_ptr) ([<список типов параметров>]);

Таким образом, при объявлении указателя на функцию необходимо задавать и тип возвращаемого функцией значения, и спецификацию ее параметров. Скобки при имени указателя обязательны, потому что приоритет операции ‘()’ выше приоритета операции ‘*’: при отсутствии скобок получится прототип функции, возвращающей значение указателя на <спецификация типа>.

В примере 4.1 в главной функции по формуле Симпсона рассчитываются приближенные значения определенных интегралов 3-х функций   y = f(x), где

f(x) =

Отрезок интегрирования [a, b] разбивается на n равных частей, n – количество узлов, для формулы Симпсона n – нечетное  (т.е. n = 2m, где – m натуральное число):

    ≈ .

Здесь h = (b – a)\n,  = f(a), == f(b),  = f(a + ih)  для  i  = .

Для вычисления значения функции, y, от некоторого значения параметра, x, описаны функции fun_1(), fun_2() и fun_3(). Заголовки этих трех функций различаются только идентификаторами – именами функций. Тип возвращаемого функциями значения – double, тип единственного формального параметра функций – double. Поэтому указатель на любую из этих функций, fun, объявлен в функции main() как переменная-указатель  следующим образом:

double (*fun)( double );

Указателю на функцию можно присваивать адреса функций и значения других указателей на функции «соответствующих типов». Формулировка «соответствующих типов» означает, что  совпадают типы возвращаемых значений функций, кроме того, функции имеют одинаковые списки формальных параметров: имеется в виду количество и типы параметров.

В функции main()  :

·  в соответствии с оператором объявления  double (*fun)( double );  –  объявлена переменная-указатель на функцию, возвращающую значение типа double и имеющую один параметр – значение типа double.

·  оператор присваивания fun = fun_1; (так же, как операторы fun = fun_2; fun = fun_3;) –  демонстрирует инициализацию объявленной переменной-указателя на функцию: адресное выражение funприобретает значение, равное адресу функции fun_1.  

·  оператор присваивания rezult = (*fun)(a)+ fun(b); –  демонстрирует 2 способа вызова одной из 3-х функций: значения функции вычисляются  в точках a и b (границах  отрезка интегрирования) и  сумма этих значений присваивается переменной result.

 Замечание. В первом слагаемом скобки около идентификатора fun обязательны: их отсутствие приведет к недопустимой операции взятия значения не по адресу, а по значению, являющимся возвращаемым значением функции, адресуемой указателем fun.

Пример4.1.

# include <stdio.h>

# include <math.h>

double fun_1( double x)  { return (2*x*x*x - 3*x*x + 5*x +1);}

double fun_2( double x) { return (1/(1+x*x));}

double fun_3( double x)  { return (exp(-x*x));}

void main(void)

{   int i, n, numb_f=1;     double a , b , h, rezult;

 double (*fun)( double ); /* объявлен указатель на функцию типа double с единственным параметром типа double */

printf("\nVvod n = "); scanf("%d",&n);

    printf("\nVvod a = ");  scanf("%lf",&a);

    printf("\nVvod b < a, b = ");  scanf("%lf",&b);       h=(b-a)/n;

   while (numb_f < 4)

{ if (numb_f == 1) fun=fun_1;  /* настройка   на функцию fun_1() */

if (numb_f == 2) fun=fun_2;  /* настройка   на функцию fun_2() */

if (numb_f == 3) fun=fun_3; /* настройка  на функцию fun_3() */

rezult = (*fun)(a)+ fun(b);   /* 2 способа вызова функции по адресу*/

for (i=1;i<n;i++)

                    if (i%2) rezult+=4*fun(a+i*h);

                    else rezult+=2*fun(a+i*h);

            rezult = rezult*h/3;

            printf("\n Integral = %lf",rezult);

numb_f++;

          }

}

Обобщая пример 4.1, можно привести следующие 3 формы вызова функции:

·  имя_функции(список_аргументов);

·  имя_указателя(список_аргументов);

·  (*имя_указателя)(список_аргументов).

4.3.ОБЪЯВЛЕНИЕ МАССИВА УКАЗАТЕЛЕЙ НА ФУНКЦИИ