Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Лекции_по_пяву_4.doc
Скачиваний:
101
Добавлен:
15.03.2015
Размер:
1.29 Mб
Скачать
      1. Инициализация указателя на функцию

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

Пусть имеются две функции, имеющие следующие прототипы.

double sqr(double x); double cube(double x);

Объявим три указателя на функцию:

double (*pf1)(double) = &sqr; double (*pf2)(double)= cube;

double(*pf3)(double)= 0;

Синтаксис, с которым объявлены первые две переменные (pf1 иpf2), несколько отличаются. Синтаксис, с которым объявлена первая переменная (pf1) не вызывает сомнений в корректности. Справа от знака присваивания находится выражение, значением которого является адрес функции. Могут возникнуть сомнения в корректности второго объявления, где объявлена переменнаяpf2. В этом объявлении в качестве инициализатора используется имя функции, а не ее адрес. Однако этот код нормально компилируется. Дело в том, что языке Си всегда в том коде, где ожидается указатель на функцию, а встречается имя функции, выполняется автоматическое преобразование имени функции в указатель.

Замечание. Операция инициализации выполняется и при использовании казателя на функцию в качестве формального параметра функции.

      1. Операции с указателями на функцию

С указателями на функцию можно выполнять следующие операции.

  1. Вызов функции, на которую установлен указатель.

  2. Присваивание однотипных указателей.

  3. Указатель можно использовать в качестве формального параметра функции.

  4. Функция может возвращать значение, имеющее тип указателя на функцию.

Вызов функции через указатезатель на функцию.

Вначале рассмотрим вызов функции с помощью указателя на функции. Существуют две формы вызова через указатель на функцию.

Первая форма.

(*<α>)(<>)

Вторая форма

<α>(<>)

Здесь αимя указателя на функцию, а - список фактических параметров вызываемой функции. Первая форма строго следует синтакису языка Си, а во второй форме выполняется автоматическое разыменование указателя на функцию. В качестве примера рассмотрим следующий программный код.

double (*pf)(double) = &sqr; printf(“%0.4g\n”, (*pf)(3))); printf(“%0.4g\n”, pf(4));

В результате выполнения первого вызова функции printf() на экране появится число 9, а при выполнении второго вызова функцииprintf() на экране появится число 16.

Присваивание указателей на функцию.

Любому указателю на функцию может быть присвоено значение нулевого указателя. Например.

double(*pf)(double);pf= 0;

Можно присваивать указателю на функцию значение другого однотипного указателя на функцию. Например.

double(*pf1)(double) =sqr;double(*pf2)(double) =cube;double(*pf3) (double,double);pf1 =pf2; //Нормально.Указателиpf1 иpf2 имеют один и тот же //типpf1 =pf3; //Ошибка. Указателиpf1 иpf3 имеют разные типы.

Для иллюстрации использования указателей на функцию в качесте параметров функций рассмотрим два примера

      1. Табулирование произвольной функции одного переменного

Постановка задачи

Написать функцию пользователя, предназначенную для табулирования произвольной математической функции одного переменного. Табулирование следует выполнять в “n” равноотстоящих точках, начиная отx= хнач вполоть доx= хкон.

Решение

Программа, предназначенная для демонстрации решения поставленной задачи, состоит из трех файлов:

  • Файл bibl.c, который содержит определение функцииtable(), выполняющей табулирование, и определения табулируемых функций:sqr()иcube().

  • Файл bibl.h, который содержит объявления используемых функций.

  • Файл main.c, который содержит тестовую программу.

/*Файл bibl.h */ double sqr(double x);doublecube(doublex); /* Объявления других табулируемых функций */voidtable(double(*pf)(doublex),doublexn,doublexk,intn); /*Файл bibl.c */ #include <stdio.h> /* Вычисление квадрата аргумента. Первая из табулируемых функций. */double sqr(double x) {returnx * x; } /* Вычисление третьей степени аргумента. Вторая из табулируемых функций */double cube(double x) {returnx * x * x; }

/* Определения других табулируемых функций*/

/* Функция,выполняющая табулирование. Через первый параметр этой функции передается табулируемая функция */

voidtable(double(*pf)(doublex),doublexn,doublexk,intn) {doublex, dx;inti; printf("%5s%10s%10s\n", "НОМЕР", "АРГУМЕНТ", "ФУНКЦИЯ"); x = xn; dx = (xk - xn) / (n - 1);for(i = 1; i <= n; i++) { printf("%5d%10.2f%10.2\n", i, x, f(x)); x += dx; } } /*Файл main.c */ #include”bibl.h”int main(void) {doublexn, xn:intn; printf(“Количество расчетных точек=”) scanf(“%d”, &n); printf(“Начальное значение аргумента=”); scanf(“%lf”, &xn); printf(“Конечное значение аргумента=”); scanf(“%lf”, &xк); /* Табулирование функции y = x2*/ table(sqr, xn, xk, n); /* Табулирование функции y = x3*/ table(cube, xn, xk, n);return 0; }