Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Функции.doc
Скачиваний:
8
Добавлен:
24.11.2018
Размер:
361.47 Кб
Скачать
  1. Передача функции в качестве параметра в функцию

3.1Указатель на функцию

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

Общий вид определения указателя на функцию:

Тип_результата (*имя_указателя_на_функцию) (список типов параметров);

Примеры:

Void (*pf) (int);

Здесь pf – указатель на функцию, не возвращающую результат и принимающую параметр типа int.

int (*f) (float, int *);

Здесь f указатель на функцию, возвращающую результат типа int и имеющую два параметра - первый типа float, второй параметр - указатель на число типа int.

При определении указателя на функцию разрешается одновременно с указанием типа параметров задавать их имена. Например,

char* (*comp) (char *s1, char *s2);

Здесь comp – указатель на функцию, возвращающую результат – указатель на char и принимающую в качестве параметров два указателя на char.

Указатели на функцию передаются в качестве аргумента другим функциям, если последние реализуют какой-либо метод обработки функций, не зависящий от вида конкретной обрабатываемой функции. Эта конкретная (фактическая) функция вызывается из тела обрабатываемой функции по переданному ей указателю.

Чтобы сделать программу легко читаемой, при описании указателей на функцию используют переименование типов (typedef). Например,

typedef float (*func) (float);

Здесь описан тип func как указатель на функцию с одним параметром типа float и возвращающую результат типа float.

Указатели на функцию используются часто. Например, многие библиотечные функции в качестве аргументов получают указатель на функцию. Использование указателей на функцию в качестве аргументов позволяет разрабатывать универсальные функции, например численного решения уравнений, численного интегрирования и дифференцирования. Массивы указателей на функции используются для организации меню.

3.2 Пример передачи имени функции в функцию

Вычислить f((a+b)/2)·(b-a) для трех функции f(x)=3x, f(x)=exsinx, f(x)=xcosx и чисел a и b.

Решение.

Ниже на рисунке дана графическая интерпретация выражения f((a+b)/2)·(b-a).

Для решения поставленной задачи необходимо разработать четыре функции. Одну из них назовем f1. Она предназначается для вычисления значения 3x . Вторую назовем f2. Она предназначается для вычисления значения exsinx. Третью функцию назовем f3. Она предназначается для вычисления значения xcosx. Четвертую функцию назовем IT. Она предназначается для вычисления значения f((a+b)/2)·(b-a) для заданной функции f.

Функции f1, f2, f3 будут передаваться в функцию f в качестве параметра. Поэтому создадим новый тип – указатель на функцию, принимающую в качестве параметра вещественное значение (float) и возвращающую указатель на вещественный тип (float). Пусть func – имя нового типа:

typedef float (*func)(float);

Функции f1, f2, f3 должны возвращать значения типа float. Описание их будет выглядеть следующим образом:

/* Описание f1 */

float f1(float x)

{ float ff=3*x;

return (ff);

}

/* Описание f2*/

float f2(float x)

{ float ff=exp(x)*sin(x);

return (ff);

}

/* Описание f3 */

float f3(float x)

{ float ff=x*cos(x);

return (ff);

}

Функция IT будет иметь три формальных параметра. Ее описание будет иметь вид:

float IT(func f, float a, float b)

{ float t=(b-a)*f((b-a)/2);

return(t);

}

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

#include<stdio.h>

#include<math.h>

#include<conio.h>

typedef float (*func)(float);

float f1 (float x);

float f2 (float x);

float f3 (float x);

float IT(func f, float a, float b);

void main()

{

float a, b;

puts("Введите числа a, b");

scanf("%f%f", &a, &b);

printf("Для a=%f b=%f \n", a, b);

printf("Значение f(f1, a, b ) равно %f\n",IT(*f1,a,b));

printf("Значение f(f2, a, b ) равно %f\n",IT(*f2,a,b));

printf("Значение f(f3, a, b ) равно %f\n",IT(*f3,a,b));

getch();

}

//Описание f1

float f1(float x)

{ float ff=3*x;

return (ff);

}

//Описание f2

float f2(float x)

{ float ff=exp(x)*sin(x);

return (ff);

}

//Описание f3

float f3(float x)

{ float ff=x*cos(x);

return (ff);

}

//Описание IT

float IT(func f, float a, float b)

{ float t=(b-a)*f((b-a)/2);

return(t);

}

В рассмотренном примере функция main() является вызывающей для функции IT. При первом обращении к функции IT ей будет передана функция f1 и значения a и b (IT(*f1,a,b)). В результате будет вычислено значение 3x при x=(b-a)/2. При втором обращении к функции IT ей будет передана функция f2 и значения a и b (IT(*f2,a,b)). В результате будет вычислено значение exsinx при x=(b-a)/2. При третьем обращении к функции IT ей будет передана функция f3 и значения a и b (IT(*f3,a,b)). В результате будет вычислено значение xcosx при x=(b-a)/2. Легко подсчитать (например в MathCad), что при а=1, в=2 должны быть получены значения 1.5, 0.790439 и 0.43879. Такие же значения получаются и при запуске программы, если ввести а=1, в=2.

Замети, что если не создавать новый тип func, то прототип функции IT будет иметь вид:

float IT(float (*f)(float), float a, float b);

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]