Синтаксическая форма объявления указателя на функцию имеет вид:
<спецификация типа> (*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.ОБЪЯВЛЕНИЕ МАССИВА УКАЗАТЕЛЕЙ НА ФУНКЦИИ
Уважаемый посетитель!
Чтобы распечатать файл, скачайте его (в формате Word).
Ссылка на скачивание - внизу страницы.