Структуры и алгоритмы компьютерной обработки данных

Тип указатель: указатели на функции

Разбить на страницы
Показывать лекцию целиком

Цель лекции: изучить указатели на функции и методы передачи функций как параметров, научиться использовать указатели на функции в программных кодах на языке 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);

    это не определение указателя, а объявление (прототип) функции c именем 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;
    }

    Ключевые термины

    Адрес функции – это адрес памяти, с которого начинается машинный код функции.

    Косвенное обращение по указателю на функцию – это вызов функции, адресуемой указателем.

    Указатели на функции как параметры функции – это параметры функции, типы которых определены как указатели на функции.

    Указатель на функцию – это переменная, которая содержит адрес этой функции.

    Краткие итоги

  • Адресация функций осуществляется по первому байту расположения машинного кода функции в памяти.
  • Инициализированный указатель на функцию содержит адрес этой функции.
  • Арифметические операции над указателями на функции запрещены в силу их внутреннего представления.
  • При описании указателя на функцию необходимо соблюдать приоритет операций. Разыменование имеет низкий приоритет, поэтому порядок действий определяется круглыми скобками.
  • При описании указателя на функцию в качестве параметров можно указывать пустой список или список типов параметров.
  • При вызове функции через указатель необходимо, чтобы типы и набор фактических параметров совпадали с прототипом адресуемой функции.
  • Функции можно передавать в качестве параметров функций.
  • Указатели на функции и указатели как параметры функции имеют широкое практическое применение в программировании.
  • Лабораторная работа 5. Тип указатель: указатели на функции.

    Цель работы: изучить указатели на функции и методы передачи функций как параметров, научиться использовать указатели на функции в программных кодах на языке C++.

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

    Теоретические сведения.

    Ознакомьтесь с материалом лекции 5.

    Задания к лабораторной работе.

  • Методом половинного деления решите уравнения на отрезке $$[a, b]$$ с данной точностью $$е: \cos x=x^2,\quad 0,6\sqrt[3]{x}=\log_5 x$$. При решении считать, что на данном отрезке существует единственный корень. Решите первое уравнение на отрезке [0, 1], а второе на отрезке [100, 150].
  • Решите задачу, используя один указатель на функцию. Разработайте четыре функции над двумя целыми параметрами, соответствующие арифметическим операциям (+, -, *, /). В основной программе задавайте два целых параметра и символьный знак операции до тех пор, пока не будет введен пробел в качестве знака операции. В выходных данных выводите значения функций.
  • Вычислите суммы с данной точностью е. Используйте указатели на функции как параметры: $$\sum_{n=1}^{\infty}\frac{\sin n}{n}$$ и $$\sum_{n=1}^{\infty}\frac{n}{e^n}$$.
  • Указания к выполнению работы.

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

    Следует реализовать каждое задание в соответствии с приведенными этапами:

  • изучить словесную постановку задачи, выделив при этом все виды данных;
  • сформулировать математическую постановку задачи;
  • выбрать метод решения задачи, если это необходимо;
  • разработать графическую схему алгоритма;
  • записать разработанный алгоритм на языке С++;
  • разработать контрольный тест к программе;
  • отладить программу;
  • представить отчет по работе.
  • Требования к отчету.

    Отчет по лабораторной работе должен соответствовать следующей структуре.

  • Титульный лист.
  • Словесная постановка задачи. В этом подразделе проводится полное описание задачи. Описывается суть задачи, анализ входящих в нее физических величин, область их допустимых значений, единицы их измерения, возможные ограничения, анализ условий при которых задача имеет решение (не имеет решения), анализ ожидаемых результатов.
  • Математическая модель. В этом подразделе вводятся математические описания физических величин и математическое описание их взаимодействий. Цель подраздела – представить решаемую задачу в математической формулировке.
  • Алгоритм решения задачи. В подразделе описывается разработка структуры алгоритма, обосновывается абстракция данных, задача разбивается на подзадачи. Схема алгоритма выполняется по ЕСПД (ГОСТ 19.003-80 и ГОСТ 19.002-80).
  • Листинг программы. Подраздел должен содержать текст программы на языке программирования С++, реализованный в среде MS Visual Studio 2010.
  • Контрольный тест. Подраздел содержит наборы исходных данных и полученные в ходе выполнения программы результаты.
  • Выводы по лабораторной работе.
  • Ответы на контрольные вопросы.
  • Контрольные вопросы

  • Почему запрещены арифметические операции над указателями на функции?
  • Почему в описании указателя на функцию необходимы круглые скобки при имени указателя?
  • Может ли функция возвращать значение типа указатель? Если да, то как объявляется прототип такой функции?
  • Могут ли параметрами функции быть указатели на объекты? Если да, то как происходит передача фактических параметров при вызове функции?
  • Могут ли параметрами функции быть указатели на функции? Если да, то как происходит передача фактических параметров при вызове функции?
  • Как понимается следующее объявление:
    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);

    это не определение указателя, а объявление (прототип) функции c именем 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;
    }

    Ключевые термины

    Адрес функции – это адрес памяти, с которого начинается машинный код функции.

    Косвенное обращение по указателю на функцию – это вызов функции, адресуемой указателем.

    Указатели на функции как параметры функции – это параметры функции, типы которых определены как указатели на функции.

    Указатель на функцию – это переменная, которая содержит адрес этой функции.

    Краткие итоги

  • Адресация функций осуществляется по первому байту расположения машинного кода функции в памяти.
  • Инициализированный указатель на функцию содержит адрес этой функции.
  • Арифметические операции над указателями на функции запрещены в силу их внутреннего представления.
  • При описании указателя на функцию необходимо соблюдать приоритет операций. Разыменование имеет низкий приоритет, поэтому порядок действий определяется круглыми скобками.
  • При описании указателя на функцию в качестве параметров можно указывать пустой список или список типов параметров.
  • При вызове функции через указатель необходимо, чтобы типы и набор фактических параметров совпадали с прототипом адресуемой функции.
  • Функции можно передавать в качестве параметров функций.
  • Указатели на функции и указатели как параметры функции имеют широкое практическое применение в программировании.
  • Лабораторная работа 5. Тип указатель: указатели на функции.

    Цель работы: изучить указатели на функции и методы передачи функций как параметров, научиться использовать указатели на функции в программных кодах на языке C++.

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

    Теоретические сведения.

    Ознакомьтесь с материалом лекции 5.

    Задания к лабораторной работе.

  • Методом половинного деления решите уравнения на отрезке $$[a, b]$$ с данной точностью $$е: \cos x=x^2,\quad 0,6\sqrt[3]{x}=\log_5 x$$. При решении считать, что на данном отрезке существует единственный корень. Решите первое уравнение на отрезке [0, 1], а второе на отрезке [100, 150].
  • Решите задачу, используя один указатель на функцию. Разработайте четыре функции над двумя целыми параметрами, соответствующие арифметическим операциям (+, -, *, /). В основной программе задавайте два целых параметра и символьный знак операции до тех пор, пока не будет введен пробел в качестве знака операции. В выходных данных выводите значения функций.
  • Вычислите суммы с данной точностью е. Используйте указатели на функции как параметры: $$\sum_{n=1}^{\infty}\frac{\sin n}{n}$$ и $$\sum_{n=1}^{\infty}\frac{n}{e^n}$$.
  • Указания к выполнению работы.

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

    Следует реализовать каждое задание в соответствии с приведенными этапами:

  • изучить словесную постановку задачи, выделив при этом все виды данных;
  • сформулировать математическую постановку задачи;
  • выбрать метод решения задачи, если это необходимо;
  • разработать графическую схему алгоритма;
  • записать разработанный алгоритм на языке С++;
  • разработать контрольный тест к программе;
  • отладить программу;
  • представить отчет по работе.
  • Требования к отчету.

    Отчет по лабораторной работе должен соответствовать следующей структуре.

  • Титульный лист.
  • Словесная постановка задачи. В этом подразделе проводится полное описание задачи. Описывается суть задачи, анализ входящих в нее физических величин, область их допустимых значений, единицы их измерения, возможные ограничения, анализ условий при которых задача имеет решение (не имеет решения), анализ ожидаемых результатов.
  • Математическая модель. В этом подразделе вводятся математические описания физических величин и математическое описание их взаимодействий. Цель подраздела – представить решаемую задачу в математической формулировке.
  • Алгоритм решения задачи. В подразделе описывается разработка структуры алгоритма, обосновывается абстракция данных, задача разбивается на подзадачи. Схема алгоритма выполняется по ЕСПД (ГОСТ 19.003-80 и ГОСТ 19.002-80).
  • Листинг программы. Подраздел должен содержать текст программы на языке программирования С++, реализованный в среде MS Visual Studio 2010.
  • Контрольный тест. Подраздел содержит наборы исходных данных и полученные в ходе выполнения программы результаты.
  • Выводы по лабораторной работе.
  • Ответы на контрольные вопросы.
  • Контрольные вопросы

  • Почему запрещены арифметические операции над указателями на функции?
  • Почему в описании указателя на функцию необходимы круглые скобки при имени указателя?
  • Может ли функция возвращать значение типа указатель? Если да, то как объявляется прототип такой функции?
  • Могут ли параметрами функции быть указатели на объекты? Если да, то как происходит передача фактических параметров при вызове функции?
  • Могут ли параметрами функции быть указатели на функции? Если да, то как происходит передача фактических параметров при вызове функции?
  • Как понимается следующее объявление:
    float *(*func)(int(*pf)(char),float);?
  • В чем отличие результатов вызова функции через указатель с последующим разыменованием указателя и без разыменования указателя?
  • Вернуться к учебному плану