Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Информатика 1.docx
Скачиваний:
11
Добавлен:
26.09.2019
Размер:
364.88 Кб
Скачать

Указатели на функции.

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

класс_памяти тип (*имя)(список параметров);

Например,

int (*fun)(int x, int *y);

Здесь объявлена переменная fun как указатель на функцию с двумя параметрами: типа int и указателем на int. Сама функция должна возвращать значение типа int. Круглые скобки, содержащие имя указателя fun и признак указателя *, обязательны, иначе запись

int *fun (int x, int *y);

будет интерпретироваться как объявление функции fun возвращающей указатель на int.

Корректный вызов функции возможен только после инициализации значения указателя fun (иначе произойдёт вызов по ошибочному, "мусорному" адресу, уже хранящемуся в указателе). Он имеет вид:

(*имя)(список параметров);

Например:

(*fun)(i,&j);

В этом выражении для получения функции, на которую ссылается указатель fun используется операция косвенной адресации * .

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

Пример:

double (*fun1)(int x, int y);

double fun2(int k, int l);

void main()

{

fun1=fun2; // инициализация указателя на функцию

(*fun1)(2,7); // обращение к функции

}

В рассмотренном примере указатель на функцию fun1 описан как указатель на функцию с двумя параметрами, возвращающую значение типа double, и также описана функция fun2. В противном случае, т.е. когда указателю на функцию присваивается функция, описанная иначе, чем указатель, произойдет ошибка.

Рассмотрим пример использования указателя на функцию в качестве параметра функции вычисляющей производную от функции cos(x).

Пример:

double proiz(double x, double dx, double (*f)(double x) );

double fun(double z);

void main()

{

double x=5; // точка вычисления производной

scanf("%f,%f",&x,&dx); // ввод значений x и dx

z=proiz(x,fun); // вызов функции для fun

printf("fun'(%f)=%f",x,z); // печать значения производной

// печать значения производной для sin(x) и cos(x)

printf("sin'(%f)=%f cos'(%f)=%f",x,proiz(x,sin),x,proiz(x,cos));

}

double proiz(double x,double (*f)(double z) )

{

// функция, вычисляющая производную

double y1,y2,pr;

double dx=.001; // "бесконечно малое" приращение

y1=(*f)(x);

y2=(*f)(x+dx);

pr=(y2-y1)/dx;

return pr;

}

double fun( double z)

{

// функция, от которой вычисляется производная

return (2*z*z);

}

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

  1. Библиотеки функций. Различия между статическими и динамическими библиотеками. Использование стандартных библиотек C.