Главная страница

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


Скачать 0.9 Mb.
НазваниеМетодические рекомендации для студентов, изучающих программирование в С. Предназначено для студентов специальностей Прикладная математика и информатика
АнкорOutput
Дата11.04.2023
Размер0.9 Mb.
Формат файлаpdf
Имя файлаoutput (2).pdf
ТипМетодические рекомендации
#1053385
страница3 из 6
1   2   3   4   5   6

Часть 2 (до 5 баллов)
Добавьте к иерархии из предыдущего упражнения класс-наследник FunctionCall. FunctionCall должен представлять вызов одной из двух предопределенных математических функций: sqrt — извлечение квад- ратного корня и abs — вычисление модуля числа. Функция идентифицируется строкой, переданной в каче- стве параметра в конструктор. Не забудьте, что у функции должен быть аргумент (которым может быть любое выражение Expression)!
#
include // std::string
#
include
#
include // sqrt и fabs
// эти классы из предыдущего упражнения
struct Expression;
struct BinaryOperation;
struct Number;
struct FunctionCall : Expression
{
/**
* @name – это имя функции, возможные варианты
* "sqrt" и "abs".
*
* Объекты, std::string можно

24
* сравнивать с C-строками используя
* обычный синтаксис ==.
*
* @arg – выражение-аргумент функции
*/
FunctionCall(/*аргументы*/)
{
//реализация
}
// реализуйте оставшиеся методы из
// интерфейса структуры Expression и не забудьте
// удалить arg_, как это сделано в классе BinaryOperation
//также реализуйте предложенные ниже методы std::string
const & name() const
{
// реализация
}
Expression
const *arg() const
{
//реализация
}

FunctionCall(){/*реализация*/}
private:
//а тут должны быть поля для FunctionCall
};
Проверьте полученную иерархию на следующем фрагменте кода:
//------------------------------------------------------------
Expression* n32 =
new Number(32.0);
Expression* n16 =
new Number(16.0);
Expression* minus =
new BinaryOperation(n32, BinaryOperation::MINUS, n16);
Expression* callSqrt =
new FunctionCall("sqrt", minus);
Expression* n2=
new Number(2.0);
Expression* mult =
new BinaryOperation(n2, BinaryOperation::MUL, callSqrt);
Expression* callAbs =
new FunctionCall("abs", mult);
cout<evaluate()<<endl;
//------------------------------------------------------------
Часть 3 (до 7 баллов)
Создайте иерархию классов, используя наследование от абстрактного базового класса. В каждой про- грамме необходимо соблюсти принцип разделения интерфейса и реализации класса. В каждом варианте необходимо написать программу, иллюстрирующую применение всех методов ваших классов. Прежде чем приступить к написанию программ, продумайте (или посоветуйтесь с преподавателем), какие необходимы функции в каждом из классов. Также продумайте, что следует поместить в закрытые или защищенные переменные. Особенно обратите внимание на то, какие функции следует сделать чистыми виртуальными. Обязательно предусмотрите виртуальный деструктор! В основной программе обязательно используйте динамическое связывание (без него работа не принимается).

25
Варианты
1.
Координаты точки на плоскости – это способ описания ее положения в двумерном пространстве.
Способов описания может быть много, но мы ограничимся декартовыми, полярными и естествен- ными координатами. Рассмотрите класс «Координата» как базовый, а перечисленные способы опи- сания положения на плоскости реализуйте конкретными классами. Можете также поэксперимен- тировать с функциями – друзьями классов, которые могут переводить один способ описания в дру- гой.
2.
Усложним задачу №1 – перейдем в пространство. Здесь остановимся на декартовых, сферических и цилиндрических координатах. Далее сделайте то же, что и в первой задаче.
3.
Пока с утра вы едете в университет, вы являетесь пассажиром. Реализуйте абстрактный базовый класс «Пассажир» и конкретные классы – пассажир с билетом, льготной сезонкой, транспортной картой (помните, что их бывает несколько видов), «заяц». Попробуйте подсчитать, сколько пасса- жиров каждого «вида» едет в час пик и какова выручка кондуктора с них.
4.
Реализуйте иерархию Форма -> Точка -> Круг -> Сфера. Можете попробовать написать для этих классов функции рисования, а не только расчета площади, периметра и т.п.
5.
То же, что и в задаче №5, но иерархия Форма -> Точка -> Многоугольник -> Многогранник.
6.
Все мы любим отдыхать. Но абстрактное понятие «нерабочий день» может на самом деле оказать- ся конкретным выходным, праздником или отпуском. Реализуйте такую иерархию. Разумеется, са- мый большой приоритет имеют выходные
– на них могут попасть и праздники, и отпуск.
7.
Вспомним основы механики. Наиболее общее понятие «движение» конкретизировалось сначала понятиями прямолинейное и криволинейное движение. Прямолинейное движение в свою очередь еще более сильно конкретизировали: равномерное и неравномерное движение. А уж из неравно- мерного движения выделяли еще равноускоренное движение. С криволинейным все немного про- ще – достаточно рассмотреть движение по окружности как частный случай более общего криволи- нейного движения. Реализуйте иерархию классов, используя абстрактный базовый класс «Движе- ние». Не забудьте про основные характеристики движения!
8.
Напишите абстрактный класс «Студент», которому наследуют конкретные классы отличник, хо- рошист, троечник, должник. Не забудьте успевающим студентам начислить стипендию, а неуспе- вающим – дату пересдачи долгов. Естественно, количество пересдач ограничено – не более 3. Пре- дусмотрите возможность отчисления неуспевающих студентов или ухода их в академический от- пуск.
9.
При слове «Авиабилет» у вас наверняка возникают самые разные ассоциации – ведь это может быть билет на простой междугородний рейс или на международный. Это может быть билет перво- го класса, бизнес-класса, второго класса…
Реализуйте иерархию
«Авиабилет»
-> «Междугородний» -> «Международный». Помните, что требования на приобретение междуна- родного авиабилета более жесткие, значит данных в этом классе (или функций) будет больше.
10. Представьте, что вы только что выиграли чемпионат по программированию. Вы стали абстракт- ным победителем, чтобы о вас знали как о конкретном человеке, победившем в конкретном чем- пионате, надо определить несколько вещей. Во-первых, свои персональные данные (хотя бы ФИО).
Во-вторых, вид и тур соревнования: университетский тур, городской, областной, федеральный или международный. Начиная с абстрактного класса «Победитель чемпионата», реализуйте приведен- ную выше иерархию классов.

26 11. Попробуйте немного себя в роли бухгалтера, начисляющего зарплату. Само по себе понятие «Зар- плата» не особенно конкретное: оно включает и почасовую, и ставочную зарплату, и комиссион- ные, и процент с продаж (если работа связана с продажей). Реализуйте данные классы.
12. Вычислительное средство само по себе является понятием абстрактным. Оно может представлять из себя бухгалтерские счёты, арифмометр, калькулятор или современную ПЭВМ. Реализуйте та- кую иерархию.
13. Поговорим о транспортных средствах. На дороге можно встретить грузовой, легковой и пассажир- ский транспорт. Каждый из этих видов транспорта обладает общими, а также специфическими ха- рактеристиками (подумайте, какими). Напишите иерархию классов «Автомобиль» (абстрактный базовый) и далее 3 производных конкретных класса. Подумайте, какие характеристики нужны для вывода на печать, попробуйте также рассчитать средний тормозной путь, грузоподъемность, вме- стимость соответствующих транспортных средств.
14. Вся компьютерная графика делится на векторную и растровую. Так как сильно отличаются прин- ципы построения рисунков этих видов, можно выделить программы, поддерживающие тот или иной вид графики и сохраняющие рисунки в том или ином формате. Попробуйте написать про- грамму с использованием полиморфизма и абстрактного класса, реализующую данную схему.
15. Не за горами сессия, и скоро такое абстрактное понятие, как «Контроль успеваемости», превратит- ся во вполне реальное понятие зачет или экзамен (в устной или письменной форме, или, быть мо- жет, в форме теста). Подумайте, какие элементы и функции входят в абстрактный базовый класс «Кон- троль успеваемости» и как их реализовать для конкретных производных классов. Напишите про- грамму.
16. Попробуйте выстроить логическую цепочку: Студент университета N -> Студент факультета N ->
Студент специальности N -> Студент курса N. Вместо N каждый раз будет нужно подставить на- звание вуза, факультета, специальности, номер курса. Реализуйте цепочку через абстрактные и конкретные классы. Возможно, для конкретной специальности придется ввести новые предметы, а для конкретного курса – количество часов на изучение определенных дисциплин.
17. Вы уже не первый год изучаете языки программирования. Наверняка вы знаете, что их можно под- разделить на языки структурного программирования и языки объектно-ориентированного про- граммирования. К первым можно отнести, например, C и Pascal, ко вторым – C++, Java... Реализуй- те эту структуру через абстрактные и конкретные классы.
18. Понятие "здание" относится к абстрактным. Чтобы его конкретизировать, необходимо знать, явля- ется ли оно жилым домом, или торговым центром, или административным зданием, либо спортив- ным (крытый каток, бассейн) или культурным (театр) объектом... Разумеется, у всех них будут ка- кие-то общие характеристики (например, адрес), и у каждого из них – свои особенные характери- стики (скажем, у жилого дома – этажность, количество подъездов, наличие газовых коммуникаций,
ГВС, наличие и количество лифтов, наличие мусоропровода и т.д., у бассейна – количество аквато- рий и их размер (например, две 50-метровые акватории по 9 дорожек), количество мест в раздевал- ке, душ...). Реализуйте иерархию классов.
19. Все основные неорганические вещества на нашей планете можно подразделить на соли, кислоты, основания и оксиды. Естественно, все категории веществ состоят из химических элементов. Сделав класс «Химический элемент» абстрактным базовым, опишите приведенную здесь иерархию.

27
Вспомните, что все эти вещества могут взаимодействовать друг с другом, превращаясь друг в дру- га по определенным законам.
20. Напишите абстрактный класс «Учащийся». Его конкретными реализациями будут ученик, студент, аспирант. Подумайте, как выстроить подобную иерархию и какими общими и специфическими ха- рактеристиками будет обладать каждый класс. Напишите реализацию данной иерархии.
Лабораторная работа № 8. Обработка исключений
В данной лабораторной работе вам нужно написать класс исключения и программу, способную генери- ровать и обрабатывать определенный вид исключения (программа должна содержать блоки try, catch, точку throw). Позаботьтесь о том, чтобы исключение действительно могло возникнуть, продемонстрируйте рабо- ту перехватчика и обработчика исключений.
Варианты
Обработать следующие исключения:
1. Взятие квадратного корня из отрицательного числа.
2. Нехватка памяти при динамическом ее выделении.
3. Попытка записи в файл, открытый только для чтения.
4. Ввод пользователем вещественного числа вместо целого.
5. Ввод пользователем строки вместо числа.
6. Ввод пользователем специального символа вместо целого числа.
7. Взятие натурального логарифма от нуля.
8. Взятие натурального логарифма от отрицательного числа.
9. Ввод пользователем несуществующей даты, например, «31 февраля».
10. Ввод несуществующего времени, например, 56 час. 335 мин. 98 сек.
11. Ввод пользователем отрицательного возраста.
12. Ввод пользователем отрицательной зарплаты.
13. Попытка чтения из несуществующего файла.
14. Попытка записи в несуществующий файл.
15. Неопределенность вида «0/0».
16. Неопределенность вида «0*
».
17. Ввод числа, спецсимволов или русских букв вместо символов латинского алфавита.
18. Ввод числа, спецсимволов или латинских букв вместо символов русского алфавита.
19. Превышение при вводе максимально возможной длины строки.
20. Выход индекса за пределы массива.
Лабораторная работа № 9. Шаблоны
Упражнение 1.
(1 балл) Реализуйте шаблонную версию класса Array. Список всех операций, которые должен поддерживать класс Array, приведен в шаблоне кода.
Проверьте написанный код на типах int, double, string, char*, пользовательском типе Student (для студента храните имя и номер зачетки, а также оп- ределите необходимые методы — подумайте над конструкторами и деструкторами). Шаблон класса Array должен успешно работать с данными любого типа.
#include
using namespace std;
template <typename T>
class Array

28
{
private:
T* myArray; size_t n;
public:
// Список операций:
explicit Array(size_t size = 0, const T& value = T())
// конструктор класса, который создает
// Array размера size, заполненный значениями
// value типа T. Считайте что у типа T есть
// конструктор, который можно вызвать без
// без параметров, либо он ему не нужен.
{}
Array(
const Array & mas)
// конструктор копирования, который создает
// копию параметра. Считайте, что для типа
// T определен оператор присваивания.
{ }
Array()
// деструктор, если он вам необходим.
{}
Array&
operator=(const Array& mas)
// оператор присваивания.
{}
//
// две версии оператора доступа по индексу.
T&
operator[](size_t idx)
{} const T&
operator[](size_t idx) const
{} size_t size()
const {}
};
Упражнение 2. (1 балл) В предыдущей версии предполагается, что для типа T определен оператор при- сваивания или он ему не нужен (например, для примитивных типов он не нужен). При создании шаблон- ных классов контейнеров (вроде Array и не только) разумно стараться минимизировать требования к типам шаблонных параметров. Поэтому усложним задачу, реализуйте класс Array не полагаясь на то, что для типа
T определен оператор присваивания.
Подсказка: возможно, понадобится placement new и явный вызов деструктора, чтобы создавать и унич- тожать объекты, аллоцировать правильно выровненную память можно с помощью new char[N * sizeof(T)]
, где N – количество элементов массива.
#include
template T>
class Array
{
private:
T* myArray; size_t n;
public:
// Список операций:
explicit Array(size_t size=0, const T& value=T())
// конструктор класса, который создает

29
// Array размера size, заполненный значениями
// value типа T. Считайте что у типа T есть
// конструктор, который можно вызвать без
// без параметров, либо он ему не нужен.
{}
Array(
const Array & mas)
// конструктор копирования, который создает
// копию параметра. Считайте, что для типа
// T определен оператор присваивания.
{ }
Array()
// деструктор, если он вам необходим.
{ }
Array&
operator=(const Array& mas)
// оператор присваивания.
{ }
// две версии оператора доступа по индексу.
T&
operator[](size_t idx)
{ } const T&
operator[](size_t idx) const
{ } size_t size()
const {}};
Упражнение 3. (1 балл) Шаблонные классы можно наследовать. Реализуйте шаблонную структуру
ValueHolder с одним типовым параметром T, унаследованную от интерфейса ICloneable. Интерфейс
ICloneable содержит всего один виртуальный метод ICloneable* clone() const, который должен вернуть ука- затель на копию объекта, на котором он был вызван (объект должен быть создан в куче). Шаблон
ValueHolder, как говорит его название, хранит всего одно значение (назовите его data_) типа T (для типа T определен конструктор копирования). Не делайте поле data_ закрытым (поэтому в данном случае мы явно пишем, что ValueHolder должна быть структурой).
struct ICloneable
{
virtual ICloneable* clone() const = 0;
virtual ICloneable() { }
};
// Шаблон ValueHolder с типовым параметром T,
// должен содержать одно открытое поле data_
// типа T.
// В шаблоне ValueHolder должен быть определен
// конструктор от одного параметра типа T,
// который инициализирует поле data_.
//
// Шаблон ValueHolder должен реализовывать
// интерфейс ICloneable, и возвращать указатель
// на копию объекта созданную в куче из метода
// clone.
Упражнение 4.
(1 балл) Реализуйте функцию копирования элементов copy_n из массива источника ти- па U* в целевой массив типа T*, где T и U произвольные типы, для которых определено преобразование из

30
U в T. На вход функция принимает два указателя и количество элементов, которые необходимо скопиро- вать.
Пример вызова функции copy_n: int ints[] = {1, 2, 3, 4}; double doubles[4] = {}; copy_n(doubles, ints, 4);
// теперь в массиве doubles содержатся
// элементы 1.0, 2.0, 3.0 и 4.0
#
include
// Параметры функции copy_n идут в следующем
// порядке:
// 1. целевой массив
// 2. массив источник
// 3. количество элементов, которые нужно
// скопировать
//
// Вам нужно реализовать только функцию copy_n,
// чтобы ее можно было вызвать так, как показано
// в примере.
Упражение 5. (1 балл) Реализуйте шаблонную функцию minimum, которая находит минимальный эле- мент, который хранится в экземпляре шаблонного класса Array, при этом типовой параметр шаблона Array может быть произвольным. Чтобы сравнивать объекты произвольного типа, на вход функции также будет передаваться компаратор, в качестве компаратора может выступать функция или объект класса с перегру- женным оператором «круглые скобки» "()".
Примеры вызова функции minimum:
bool less(int a, int b) { return a < b; }
struct Greater
{
bool operator()(int a, int b) { return b < a; } };
Array<
int> ints(3); ints[0] = 10; ints[1] = 2; ints[2] = 15;
int min = minimum(ints, less); // в min должно попасть 2
int max = minimum(ints, Greater()); // в max должно попасть 15
#
include
template <typename T>
class Array
{
public: explicit Array(size_t size = 0, const T& value = T());
Array(
const Array& other);
Array();

31
Array& operator=(Array other);
void swap(Array &other); size_t size() const;
T& operator[](size_t idx);
const T& operator[](size_t idx) const;
private: size_t size_;
T *data_;
};
// Ваш код
Упражнение 6.
(2 балла) Шаблонный класс Array может хранить объекты любого типа, для которого определён конструктор копирования, в том числе и другой Array, например, Array< Array >. Глубина вложенности может быть произвольной. Напишите шаблонную функцию (или несколько) flatten, которая принимает на вход такой "многомерный" Array неизвестной заранее глубины вложенности и выводит в по- ток out через пробел все элементы, хранящиеся на самом нижнем уровне.
Примеры работы функции flatten:
Array<
int> ints(2, 0);
ints[0] = 10;
ints[1] = 20;
flatten(ints, std::cout); // выводит на экран строку "10 20"
Array< Array > array_of_ints(2, ints); flatten(array_of_ints, std::cout);
// выводит на экран строку "10 20 10 20"
Array doubles(10, 0.0); flatten(doubles, std::cout);
// работать должно не только для типа int
Примечание: лидирующие и завершающие пробельные символы будут игнорироваться, т. е. там где ожидается "10 20" будет так же принят, например, вариант " 10 20 ", но не вывод "1020".
Подсказка: шаблонные функции тоже можно перегружать, из нескольких шаблонных функций будет выбрана наиболее специфичная.
#
include
// Весь вывод должен осущствляться в поток out,
// переданный в качестве параметра.
//
// Можно заводить любые вспомогаетльные функции,
// структуры или даже изменять сигнатуру flatten,
// но при этом все примеры вызова из задания должны
// компилироваться и работать.
Упражнение
7.
(1 балл) Выше вы реализовали простой шаблон ValueHolder, в этом задании мы исполь- зуем его чтобы написать класс Any (интересно, что не шаблонный), который позволяет хранить значения любого типа! Например, вы сможете создать массив объектов типа Any, и сохранять в них int-ы, double-ы или даже объекты Array. Подробности в шаблоне кода.
Подсказка: в нешаблонном классе Any могут быть шаблонные методы, например, шаблонный конст- руктор.

32
struct ICloneable;
// Поле data_ типа T в классе ValueHolder
// открыто, к нему можно обращаться
template T>
struct ValueHolder;
// Это класс, который вам нужно реализовать
class Any
{
public:
// В классе Any должен быть конструктор, который можно вызвать
// без параметров, чтобы работал следующий код:
// Any empty; // empty ничего не хранит
// В классе Any должен быть шаблонный конструктор от одного
// параметра, чтобы можно было создавать объекты типа Any,
// например, следующим образом:
// Any i(10); // i хранит значение 10
// Деструктор: выделенные ресурсы нужно освободить.
// В классе Any также должен быть конструктор копирования (вам
// поможет метод clone интерфейса ICloneable)
// В классе должен быть оператор присваивания и/или шаблонный
// оператор присваивания, чтобы работал следующий код:
// Any copy(i); // copy хранит 10, как и i
// empty = copy; // empty хранит 10, как и copy
// empty = 0; // а теперь empty хранит 0
// Чтобы получать хранимое значение, определите в классе Any
// шаблонный метод cast, который возвращает указатель на
// хранимое значение, или нулевой указатель в случае
// несоответствия типов или если объект Any ничего не хранит:
// int *iptr = i.cast(); // *iptr == 10
// char *cptr = i.cast(); // cptr == 0,
// // потому что i хранит int, а не char
// Any empty2;
// int *p = empty2.cast(); // p == 0
// При реализации используйте dynamic_cast.
};
Упражнение
8.
(1 балл) В качестве упражнения на частичную специализацию шаблонов классов вам предлагается реализовать простой шаблон SameType. Этот шаблон не содержит никаких методов, а только одно статическое константное поле типа bool с именем value. Шаблон принимает два типовых параметра, и если два типовых параметра шаблона являются одним и тем же типом, то статическое поле value должно хранить значение true, в противном случае – значение false.

33
Примеры:
struct Dummy { };
typedef int type; std::cout << SameType<
int, int>::value << std::endl;
// выведет 1, т. е. true std::cout << SameType<
int, type>::value << std::endl;
// 1, type == int std::cout << SameType<
int, int&>::value << std::endl;
// 0, int и ссылка на int - различные типы std::cout << SameType::value << std::endl; // 1 std::cout << SameType<
int, const int>::value << std::endl;
// 0, const - часть типа
// Определите шаблон SameType с двумя типовыми параметрами.
// В шаблоне должна быть определена одна статическая константа // типа bool с именем value
Упражнение
9. (1 балл)
Реализуйте функцию array_size, которая возвращает размер массива, передан- ного в качестве параметра. Функция должна работать только для массивов! Т. е. если функции передать указатель, должна произойти ошибка компиляции.
Примеры:
int ints[] = {1, 2, 3, 4};
int *iptr = ints;
double doubles[] = {3.14}; array_size(ints); // вернет 4
array_size(doubles); // вернет 1
array_size(iptr); // тут должна произойти ошибка компиляции
Подсказка: можно организовать передачу в функцию массивов только заданного размера (передача массива по ссылке), совместите его с вашими знаниями о шаблонах.
Лабораторная работа № 10. Обобщенные контейнеры STL
1   2   3   4   5   6


написать администратору сайта