Цель лекции: изучить указатели на функции и методы передачи функций как параметров, научиться использовать указатели на функции в программных кодах на языке C++.
Функции, как и элементы данных, имеют адреса. Адресом функции является адрес памяти, с которого начинается машинный код функции.
Для того, чтобы использовать в программе указатель на функцию, необходимо выполнить следующие действия:
Каждая функция характеризуется типом
Указатель на функцию – переменная, которая содержит адрес некоторой функции. Соответственно, косвенное обращение по этому указателю представляет собой вызов функции.
Синтаксис определения указателя на функцию:
тип_функции(*имя_указателя)(спецификация_параметров)
где тип_функции – определяет тип возвращаемого функцией значения; имя_указателя – идентификатор; спецификация_параметров – определяет состав и типы
Например:
int (*pf)(); // без контроля параметров вызова int (*pf)(void); // без параметров, с контролем по прототипу int (*pf)(int, char*); // с контролем по прототипу
В соответствии с принципом контекстного определения типа данных эту конструкцию следует понимать так: pf – переменная, при косвенном обращении к которой вызывается функция с соответствующим прототипом, например int_F(int, char*), то есть pf содержит адрес функции или указатель на функцию. Следует обратить внимание на то, что в определении указателя присутствует прототип – указатель ссылается не на произвольную функцию, а только на одну из функций с заданной схемой
В определении указателя количество и тип параметров должны совпадать с соответствующими типами в определении функции, на которую ставится указатель.
Например,
int (*func1Prt)(char);
задает определение указателя func1Prt на функцию с параметром типа char, возвращающую значение типа int.
Важнейшим элементом в определении указателя на функцию являются круглые скобки. Так следующий фрагмент:
int *func(char);
это не определение указателя, а объявление (func и параметром типа char, возвращающей значение указателя типа int *. В этом случае указатель указывает на значение функции.
Если же выполнить объявление:
char *(*func2Prt)(char *,int);
то определение указателя func2Prt на функцию с параметрами типа указатель на char и типа int, возвращающую значение типа указатель на char.
Синтаксис вызова функции с помощью указателя:
(*имя_указателя)(список_фактических_параметров);
значением имя_указателя служит адрес функции, а с помощью операции * обеспечивается обращение по адресу к этой функции.
Указатели на функции в основном используются в следующих случаях.
qsort() получает четвертым аргументом указатель на составляемую пользователем В определении указателя на функцию тип
Пример 1.
//Определение и использование указателей на функции
#include "stdafx.h"
#include <iostream>
using namespace std;
//Определение и использование указателей на функции
void f1(); //объявление (прототип)функции f1
void f2(); //объявление (прототип)функции f2
int _tmain(int argc, _TCHAR* argv[]) {
void (*ptr)(); //ptr - указатель на функцию
f2(); //явный вызов функции f2
ptr=f2;//указателю присваивается адрес функции f2
(*ptr)();
//вызов функции f2 по ее адресу с разыменованием указателя
ptr=f1;//указателю присваивается адрес функции f1
(*ptr)();
//вызов функции f1 по ее адресу с разыменованием указателя
ptr(); // вызов функции f1 без разыменования указателя
system("pause");
return 0;
}
//описание функции f1 и f2
void f1() {
cout << "Выполняется f1\n";
}
void f2() {
cout << "Выполняется f2\n";
}
Пример 2.
//Вариант 1 использования указателя на функцию
#include "stdafx.h"
#include <iostream>
using namespace std;
float plus(float, float); //Объявление (прототип) функции
int _tmain(int argc, _TCHAR* argv[]){
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));
system("pause");
return 0;
}
//Описание функции сложения двух аргументов
float plus(float a, float b) {
return a+b;
}
//Вариант 2 использования указателя на функцию
#include "stdafx.h"
#include <iostream>
using namespace std;
float plus(float, float); //Объявление (прототип)функции
int _tmain(int argc, _TCHAR* argv[]){
float x=2.1, y=4.89;
float (*func)(float, float)=plus;
//определение указателя на функцию plus
printf("Сумма равна %.3f\n",plus(x,y));
//указателю присвоить адрес точки входа в функцию plus (Используем указатель на функцию)
printf("Сумма = %.3f\n",func(x,y));
system("pause");
return 0;
}
//Описание функции сложения двух аргументов
float plus(float a, float b) {
return a+b;
}
Указатели на функции как параметры позволяют создавать функции, реализующие тот или иной метод обработки другой функции, которая заранее не определена. Например, можно определить функцию для вычисления
Пример 3: Вычислите приближенное значение интегралов с помощью формулы прямоугольников, задав пределы интегрирования [a, b] и число интервалов разбиения $$(N): \int\limits_a^b \frac{xdx}{(x^2+1)^2}$$ и $$\int\limits_a^b 4\cos^2 xdx$$.
#include "stdafx.h"
#include <iostream>
using namespace std;
//Объявление (прототипы) функций:
/*функция 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);
int _tmain(int argc, _TCHAR* argv[]){
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));
system("pause");
return 0;
}
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;
}
Адрес функции – это адрес памяти, с которого начинается машинный код функции.
Косвенное обращение по указателю на функцию – это вызов функции, адресуемой указателем.
Указатели на функции как параметры функции – это
Указатель на функцию – это переменная, которая содержит адрес этой функции.
Цель работы: изучить указатели на функции и методы передачи функций как параметров, научиться использовать указатели на функции в программных кодах на языке C++.
При выполнении лабораторной работы для каждого задания требуется написать программу на языке С++, которая получает на входе данные в соответствии с форматами, обозначенными условиями задач. Программа выполняет обработку входных данных в соответствии с требованиями задания и выводит результат на экран. Ввод данных осуществляется с клавиатуры с учетом требований к входным данным, содержащихся в постановке задачи. Ограничениями на входные данные является допустимый диапазон значений используемых числовых типов в языке С++.
Теоретические сведения.
Ознакомьтесь с материалом лекции 5.
Задания к лабораторной работе.
Указания к выполнению работы.
Каждое задание необходимо решить в соответствии с изученными методами работы с указателями на функции в языке С++. Программу для решения каждого задания необходимо разработать методом процедурной абстракции, используя указатели на функции и функции в качестве параметров функций. Этапы решения задач сопроводить комментариями в коде.
Следует реализовать каждое задание в соответствии с приведенными этапами:
Требования к отчету.
Отчет по лабораторной работе должен соответствовать следующей структуре.
Контрольные вопросы
float *(*func)(int(*pf)(char),float);?
Цель лекции: изучить указатели на функции и методы передачи функций как параметров, научиться использовать указатели на функции в программных кодах на языке C++.
Функции, как и элементы данных, имеют адреса. Адресом функции является адрес памяти, с которого начинается машинный код функции.
Для того, чтобы использовать в программе указатель на функцию, необходимо выполнить следующие действия:
Каждая функция характеризуется типом
Указатель на функцию – переменная, которая содержит адрес некоторой функции. Соответственно, косвенное обращение по этому указателю представляет собой вызов функции.
Синтаксис определения указателя на функцию:
тип_функции(*имя_указателя)(спецификация_параметров)
где тип_функции – определяет тип возвращаемого функцией значения; имя_указателя – идентификатор; спецификация_параметров – определяет состав и типы
Например:
int (*pf)(); // без контроля параметров вызова int (*pf)(void); // без параметров, с контролем по прототипу int (*pf)(int, char*); // с контролем по прототипу
В соответствии с принципом контекстного определения типа данных эту конструкцию следует понимать так: pf – переменная, при косвенном обращении к которой вызывается функция с соответствующим прототипом, например int_F(int, char*), то есть pf содержит адрес функции или указатель на функцию. Следует обратить внимание на то, что в определении указателя присутствует прототип – указатель ссылается не на произвольную функцию, а только на одну из функций с заданной схемой
В определении указателя количество и тип параметров должны совпадать с соответствующими типами в определении функции, на которую ставится указатель.
Например,
int (*func1Prt)(char);
задает определение указателя func1Prt на функцию с параметром типа char, возвращающую значение типа int.
Важнейшим элементом в определении указателя на функцию являются круглые скобки. Так следующий фрагмент:
int *func(char);
это не определение указателя, а объявление (func и параметром типа char, возвращающей значение указателя типа int *. В этом случае указатель указывает на значение функции.
Если же выполнить объявление:
char *(*func2Prt)(char *,int);
то определение указателя func2Prt на функцию с параметрами типа указатель на char и типа int, возвращающую значение типа указатель на char.
Синтаксис вызова функции с помощью указателя:
(*имя_указателя)(список_фактических_параметров);
значением имя_указателя служит адрес функции, а с помощью операции * обеспечивается обращение по адресу к этой функции.
Указатели на функции в основном используются в следующих случаях.
qsort() получает четвертым аргументом указатель на составляемую пользователем В определении указателя на функцию тип
Пример 1.
//Определение и использование указателей на функции
#include "stdafx.h"
#include <iostream>
using namespace std;
//Определение и использование указателей на функции
void f1(); //объявление (прототип)функции f1
void f2(); //объявление (прототип)функции f2
int _tmain(int argc, _TCHAR* argv[]) {
void (*ptr)(); //ptr - указатель на функцию
f2(); //явный вызов функции f2
ptr=f2;//указателю присваивается адрес функции f2
(*ptr)();
//вызов функции f2 по ее адресу с разыменованием указателя
ptr=f1;//указателю присваивается адрес функции f1
(*ptr)();
//вызов функции f1 по ее адресу с разыменованием указателя
ptr(); // вызов функции f1 без разыменования указателя
system("pause");
return 0;
}
//описание функции f1 и f2
void f1() {
cout << "Выполняется f1\n";
}
void f2() {
cout << "Выполняется f2\n";
}
Пример 2.
//Вариант 1 использования указателя на функцию
#include "stdafx.h"
#include <iostream>
using namespace std;
float plus(float, float); //Объявление (прототип) функции
int _tmain(int argc, _TCHAR* argv[]){
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));
system("pause");
return 0;
}
//Описание функции сложения двух аргументов
float plus(float a, float b) {
return a+b;
}
//Вариант 2 использования указателя на функцию
#include "stdafx.h"
#include <iostream>
using namespace std;
float plus(float, float); //Объявление (прототип)функции
int _tmain(int argc, _TCHAR* argv[]){
float x=2.1, y=4.89;
float (*func)(float, float)=plus;
//определение указателя на функцию plus
printf("Сумма равна %.3f\n",plus(x,y));
//указателю присвоить адрес точки входа в функцию plus (Используем указатель на функцию)
printf("Сумма = %.3f\n",func(x,y));
system("pause");
return 0;
}
//Описание функции сложения двух аргументов
float plus(float a, float b) {
return a+b;
}
Указатели на функции как параметры позволяют создавать функции, реализующие тот или иной метод обработки другой функции, которая заранее не определена. Например, можно определить функцию для вычисления
Пример 3: Вычислите приближенное значение интегралов с помощью формулы прямоугольников, задав пределы интегрирования [a, b] и число интервалов разбиения $$(N): \int\limits_a^b \frac{xdx}{(x^2+1)^2}$$ и $$\int\limits_a^b 4\cos^2 xdx$$.
#include "stdafx.h"
#include <iostream>
using namespace std;
//Объявление (прототипы) функций:
/*функция 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);
int _tmain(int argc, _TCHAR* argv[]){
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));
system("pause");
return 0;
}
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;
}
Адрес функции – это адрес памяти, с которого начинается машинный код функции.
Косвенное обращение по указателю на функцию – это вызов функции, адресуемой указателем.
Указатели на функции как параметры функции – это
Указатель на функцию – это переменная, которая содержит адрес этой функции.
Цель работы: изучить указатели на функции и методы передачи функций как параметров, научиться использовать указатели на функции в программных кодах на языке C++.
При выполнении лабораторной работы для каждого задания требуется написать программу на языке С++, которая получает на входе данные в соответствии с форматами, обозначенными условиями задач. Программа выполняет обработку входных данных в соответствии с требованиями задания и выводит результат на экран. Ввод данных осуществляется с клавиатуры с учетом требований к входным данным, содержащихся в постановке задачи. Ограничениями на входные данные является допустимый диапазон значений используемых числовых типов в языке С++.
Теоретические сведения.
Ознакомьтесь с материалом лекции 5.
Задания к лабораторной работе.
Указания к выполнению работы.
Каждое задание необходимо решить в соответствии с изученными методами работы с указателями на функции в языке С++. Программу для решения каждого задания необходимо разработать методом процедурной абстракции, используя указатели на функции и функции в качестве параметров функций. Этапы решения задач сопроводить комментариями в коде.
Следует реализовать каждое задание в соответствии с приведенными этапами:
Требования к отчету.
Отчет по лабораторной работе должен соответствовать следующей структуре.
Контрольные вопросы
float *(*func)(int(*pf)(char),float);?
Для получения официальных документов о завершении программы дополнительного профессионального образования (удостоверения о повышении квалификации, дипломов о профессиональной переподготовке и MBA) необходимо предоставить:
Внимание! Вы можете не заказывать доставку бумажной версии официального документы, а скачать его в электронном виде и распечатать самостоятельно. Информация о выданном документе в течение 1 месяца загружается в Федеральную информационную систему «Федеральный реестр сведений о документах об образовании и (или) о квалификации, документах об обучении» - ФИС ФРДО.
Доступ на новый сайт осуществляется с использованием адреса электронной почты, который был указан вами при регистрации на "старом". Мы постарались перенести все ваши данные с прежнего ресурса, однако не исключена вероятность потери части информации.
При возникновении проблемы со входом, воспользуйтесь функцией сброса пароля
Если вы обнаружите несоответствия, пожалуйста, сообщите нам.