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

Настройку указателя на одну из 3-х функций из примера 9.1 можно осуществлять в общем виде с помощью массива указателей на функции.

Для  оператора объявления массива указателей на функции можно использовать  синтаксические формы по аналогии с формами операторов объявления массивов других объектов: символов, чисел, структур и т.д. Рассмотрим основные формы объявления массивов указателей на функции.

Форма 1. Синтаксическая форма объявления массива указателей на функции соответствует  форме оператора объявления массива объектов с учетом того, что объектом является указатель на функцию, и имеет следующий вид :

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

Объявляется массив с именем <идентификатор>,  <целое число> – количество элементов в  массиве, каждый элемент массива  –  указатель на функцию типа <спецификация типа > со списком параметров (<список типов параметров>). В случае, когда функции не имеют параметров вместо <список типов параметров> используется служебное слово void.

Например, в соответствии с оператором    float (* ptr[5])(void);   –  объявлен массив из 5-ти указателей, значением каждого может быть адрес функции без параметров, любая из функций возвращает значение типа float.

Форма 2. Оператор  <спецификация типа> (* ptr[N])(<список типов параметров>);  – допускается, если задана препроцессорная константа N.

Форма 3. Допускается объявление массива указателей с инициализацией. В этом случае в программе должны быть описаны функции, адреса которых предполагается использовать в качестве значений элементов массива указателей на функции.

В примере 4.2 в главной функции демонстрируется объявление массива указателей на функции fun_1(), fun_2() и fun_3() из примера 4.1.

Пример4.2.

void main(void)

{   int i, n, numb_f=0;

    double a , b , h, rezult;

 double (*fun[])( double ) = {fun_1,fun_2,fun_3};  /* объявленмассивуказателейнафункциитипа double сединственнымпараметромтипа double, приэтом fun[0] = fun_1,  fun[1] = fun_2,   fun[2] = fun_3 */

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 < 3)

{   rezult = (*fun[numb_f])(a)+ fun[numb_f](b);

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

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

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

    rezult = rezult*h/3;   printf("\n Integral = %lf",rezult);  numb_f++;

}

}

Замечание. Условие продолжения цикла while изменено, т.к. нумерация элементов любого массива, в том числе и массива указателей на функции, начинается с ‘0’.

Аналогичная программа из примера 4.1, не использующая массив указателей на функции, менее удобна, т.к.  добавление еще нескольких функций – подынтегральных выражений – потребует большего количества операторов.

4.4.УКАЗАТЕЛЬ НА ФУНКЦИЮ – ПАРАМЕТР ФУНКЦИИ

Использование массива указателей на функции – не единственный способ удобной организации ветвления в  программе. Иногда бывает полезно использовать адрес одной функции в качестве аргумента другой функции.

Предыдущую программу можно изменить так, как это сделано в примере 4.3. Описана дополнительная функция form_Simps(), которая по формуле Симпсона вычисляет определенный интеграл. Подынтегральное выражение задается последним параметром функции form_Simps(). Остальные параметры функции form_Simps(): n –  количество разбиений, a – нижняя граница отрезка интегрирования,  b –  верхняя граница, h –  длина отрезка.

Пример4.3.

# 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));}

    double form_Simps(int n, double a, double b, double h,double (*uk_fun)( double ))

      /* заголовок функции, которая при вызове получит адрес функции ( подынтегрального выражения),  который является ее  5-ым параметром */