Главная1-й курс3-й курс4-й курс5-й курсСпецкурсыСсылкиКарта(версия для печати)

Указатели на функции. Пример использования

А. А. Вылиток

Задача

Напечатать таблицу значений функций sin, cos, log в целых точках отрезка [1, N] c шагом 1. Значения печатать с двумя знаками после запятой.

Решение

Воспользуемся массивом структур с двумя членами: один будет содержать указатель на имя функции, другой — указатель на саму функцию. Внешний цикл будет проходить по элементам массива и печатать имя текущей функции, а внутренний цикл будет проходить по точкам отрезка и для каждой из них вызывать текущую функцию через указатель. Кроме того, необходимо сформировать заголовок таблицы. Каждое значение будем выводить в поле из 7 позиций, включающее пробел и знак вертикальной черты справа. C учетом имен функций ширина заголовка и строк таблицы составит 7(N+1) позиций. Данное решение легко модифицировать, если понадобится обрабатывать еще какие-нибудь стандартные математические функции — достаточно добавить в массив структур соответствующие элементы. Других изменений в программу вносить не придется.

В конец массива добавим струкутуру с двумя пустыми указателями — такая организация позволяет использовать while-цикл для прохода по массиву, т. е. переходить к следующему элементу на очередной итерации, пока не достигнем структуры с нулевыми указателями. Однако в данном решении мы используем for-цикл, вычислив заранее количество функций, хранящихся в массиве, с помощью константного выражения с оператором sizeof.

/*
    Вычислить значения функций в точках beg, beg+step,...,beg+step*(N-1)
*/
 
#include <stdio.h>
#include <math.h>   /* стандартый заголовок матем. функций      */ 
#define N 5         /* количество целых точек на отрезке, N<=10 */
 
struct Func
{
    char*   name;           /* имя функции   */
    double (*fp)(double);   /* адрес функции */
} func [] = {               /* инициализация */
    { "sin", &sin },
    { "cos", &cos },
    { "log", &log },
    { NULL,  NULL }
};
 
int main()
{
    int i, j,
        beg  = 1,                       /* начальная точка - левый конец отрезка */
        step = 1,                       /* расстояние между соседними точками    */
        end  = beg + ( N - 1 ) * step,  /* конечная точка - правый конец отрезка */
        /* количество функций в массиве func  */
        numfuncs = sizeof ( func ) / sizeof ( struct Func ) - 1;
 
    /*------------ печать заголовка таблицы значений -----------*/
 
    printf ( "\n" );
    for ( i = 1; i <= N+1; ++i )
        printf ( "%7s", "_______" );
 
    printf ( "\n%7s", " f(x) |" );
    for ( i = beg; i <= end; i += step )
        printf ( "%5.2f |", (double) i );
 
    printf("\n");
    for ( i = 1; i <= N + 1; ++i )
        printf ( "%7s", "-------" );
 
    /*-------------- печать значений функций ------------------*/
 
    for ( i = 0; i < numfuncs; ++i )
    {
        printf ( "\n %-5s|", func[i].name );
        for ( j = beg; j <= end; j += step )
            printf ( "%5.2f |", (*func[i].fp)( (double)j) );
    }
 
    /*-------------- завершение печати таблицы ------------------*/
 
    printf ( "\n" );
    for ( i = 1; i <= N + 1; ++i )
        printf ( "%7s", "-------" );
    printf ( "\n" );
}
 

Результат

__________________________________________
 f(x) | 1.00 | 2.00 | 3.00 | 4.00 | 5.00 |
------------------------------------------
 sin  | 0.84 | 0.91 | 0.14 |-0.76 |-0.96 |
 cos  | 0.54 |-0.42 |-0.99 |-0.65 | 0.28 |
 log  | 0.00 | 0.69 | 1.10 | 1.39 | 1.61 |
------------------------------------------