Теоретические сведения. Каждая функция характеризуется типом возвращаемого значения, именем и списком типов ее параметров

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

 

Синтаксис определения указателя на функцию:

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

где тип_функции – определяет тип возвращаемого функцией значения;

имя_указателя – идентификатор;

спецификация_параметров – определяет состав и типы параметров функции.

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

Например,

int (*func1Prt)(char);

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

Важнейшим элементом в определении указателя на функцию являются круглые скобки. Так следующий фрагмент:

int *func(char);

это не определение указателя, а объявление (прототип) функции c именем func и параметром типа char, возвращающей значение указателя типа int *. В этом случае указатель указывает на значение функции.

char *(*func2Prt)(char *,int);

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

 

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

(*имя_указателя)(список_фактических_параметров);

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

Арифметические операции над указателями на функции запрещены.

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

Пример 1.

//Определение и использование указателей на функции

#include<iostream.h>

void f1(); //объявление (прототип)функции f1

void f2(); //объявление (прототип)функции f2

 

void main() {

void (*ptr)(); //ptr - указатель на функцию

f2(); //явный вызов функции f2

ptr=f2;//указателю присваивается адрес функции f2

(*ptr)();

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

ptr=f1;//указателю присваивается адрес функции f1

(*ptr)();

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

ptr(); // вызов функции f1 без разыменованием указателя

}

 

//описание функции f1 и f2

void f1() {

cout << "Выполняется f1\n";

}

void f2() {

cout << "Выполняется f2\n";

}

Пример 2.

//Вариант 1 использования указателя на функцию

#include<stdio.h>

float plus(float, float); //Объявление (прототип) функции

 

void main() {

float x=2.1, y=4.89;

float (*func)(float,float);

//определение указателя func на функцию

printf("Сумма равна %.3f\n",plus(x,y));

func=plus;

//указателю присвоить адрес func точки входа в функцию plus

printf("(Используем указатель на функцию) Сумма =

%.3f\n",func(x,y));

}

//Описание функции сложения двух аргументов

float plus(float a, float b) {

return a+b;

}

 

 

//Вариант 2 использования указателя на функцию

#include<stdio.h>

float plus(float, float); //Объявление (прототип)функции

 

void main() {

float x=2.1, y=4.89;

float (*func)(float, float)=&plus;

//определение указателя на функцию plus

printf("Сумма равна %.3f\n",plus(x,y));

func=plus;

//указателю присвоить адрес точки входа в функцию plus

printf("(Используем указатель на функцию) Сумма =

%.3f\n",func(x,y));

}

 

//Описание функции сложения двух аргументов

float plus(float a, float b) {

return a+b;

}

 

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

Пример 3: Вычислите приближенное значение интегралов с помощью формулы прямоугольников, задав пределы интегрирования (a, b) и число интервалов разбиения (N): и .

#include <stdio.h>

#include <math.h>

//Объявление (прототипы) функций:

/*функция rectangle() возвращает значение типа double, ее параметры:*/

/*pf–указатель на функцию с параметром типа double, возвращающую значение double*/

/*a, b – пределы интегрирования, величины типа double*/

double rectangle(double(*pf)(double), double a, double b);

 

 

/*функция ratio() возвращает значение типа double, ее параметр типа double*/

double ratio(double x);

 

/*функция cos4_2() возвращает значение типа double, ее параметр типа double*/

double cos4_2(double v);

 

void main () {

double a,b,c;

printf("\nВведите значения пределов интегрирования:");

printf("\na= ");

scanf("%lf",&a);

printf("\nb= ");

scanf("%lf",&b);

c=rectangle(ratio,a,b);

printf("Первый интеграл = %f\n",c);

printf("Второй интеграл = %f\n",rectangle(cos4_2,a,b));

}

 

double rectangle(double(*pf)(double), double a, double b){

/*Вычисление определенного интеграла с помощью формулы прямоугольников*/

int N, i;

double h,s=0.0;

printf("\nВведите количество интервалов разбиения: N= ");

scanf("%d",&N);

printf("\na= ");

h=(b-a)/N; //Длина интервала разбиения

for (i=0;i<N;i++)

s+=pf(a+h/2+i*h);

return h*s;

}

 

double ratio(double x) { //Подынтегральная функция

double z; //Вспомогательная переменная

z=x*x+1;

return x/(z*z);

}

 

double cos4_2(double v){ //Подынтегральная функция

double w; //Вспомогательная переменная

w=cos(v);

return 4*w*w;

}

 

 

Задания

1.Наберите код программы из Примера 3. Выполните компиляцию и запуск программы.

2.Методом половинного деления решите уравнения на отрезке [a, b] с данной точностью е: , . При решении считать, что на данном отрезке существует единственный корень. Решите первое уравнение на отрезке [0, 1], а второе на отрезке [100, 150].

3.Решите задачу, используя один указатель на функцию. Разработайте четыре функции над двумя целыми параметрами, соответствующие арифметическим операциям (+, -, *, /). В основной программе задавайте два целых параметра и символьный знак операции до тех пор, пока не будет введен пробел в качестве знака операции. В выходных данных выводите значения функций.

Домашние задания

1.Наберите коды программ из Примеров 1 и 2. Выполните компиляцию и запуск программ.

2.Вычислите суммы с данной точностью е. Используйте указатели на функции как параметры. и .









Дата добавления: 2015-02-16; просмотров: 785;


Поиск по сайту:

При помощи поиска вы сможете найти нужную вам информацию.

Поделитесь с друзьями:

Если вам перенёс пользу информационный материал, или помог в учебе – поделитесь этим сайтом с друзьями и знакомыми.
helpiks.org - Хелпикс.Орг - 2014-2024 год. Материал сайта представляется для ознакомительного и учебного использования. | Поддержка
Генерация страницы за: 0.017 сек.