Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Программа спецкурсов кафедры ФТИ.doc
Скачиваний:
8
Добавлен:
06.06.2015
Размер:
593.92 Кб
Скачать

Программа практических занятий(36 ч.)

Ассистент Антон Валентинович Адаманский

  1. Повторение С.

  • Средства поддержки модульного программирования С: раздельная компиляция, директивы препроцессора (include, ifdef, ifndef), библиотеки.

  • Контейнеры: списки, динамический массив, ассоциативный массив

  1. Отличие программ С++ от С.

  • Ссылки

  1. Классы. Инкапсуляция.

  • Конструкторы и деструкторы

  • Модификаторы доступа

  1. Классы. Инкапсуляция (продолжение).

  • Вложенные классы

  • Переопределение операций

  1. Классы. Расширения.

  • delete[]

  • Статические члены

  • Код, генерирующийся по умолчанию: конструктор по умолчанию, конструктор копирования и оператор присваивания

  • Операторы преобразования

  • Операторы >> и <<

  • Explicit конструкторы

  1. Наследование и полиморфизм.

  2. Исключения.

  3. Потоки ввода/вывода.

  4. Шаблоны.

  5. Стандартная библиотека шаблонов (STL).

Курсовые работы

Задание № 1. Понятия класса и объекта. Механизм переопределения операций на примере классов Vector и Matrix

1) Определить класс Vector, представляющий собой вектор в трехмерном пространстве, с началом в точке (0,0,0) и концом в точке (x,y,z). Использовать float переменные для представления координат вектора. Vector должен хранить указатель на массив float. Массив создается динамически в конструкторе через оператор new. В массиве хранятся координаты конца вектора.

Определить в классе Vector следующие операции (функции):

  • конструктор копирования

  • оператор присваивания

  • деструктор

  • +, -, =, +=, -=, *(друг с другом)

  • *, /, *=, /=(со скалярным аргументам)

  • [] (взятие координаты вектора, например: v[0], v[1])

  • конструктор копирования

  • операторы >> и << для ввода/вывода вектора через cin/cout

  • invert() // поворот вектора на 180 градусов

Определить операцию умножения на скаляр, указанного в качестве первого аргумента (например v1=3*v2) как внешнюю функцию (не функцию-член класса Vector).

Написать тестовую глобальную функцию, показывающую работу каждогооператора.

Защитить состояние объекта от некорректного доступа. Везде, где возможно, использовать в качестве аргументов константные ссылки, возвращать ссылки и использовать модификатор const для функций/операторов. Например:

Vector operator+(const Vector& v1, const Vector& v2);

Vector& operator+=(const Vector& v);

float operator[](int pos) const;

float& operator[](int pos);

void print() const;

2) Используя класс Vector, написать класс Matrix, представляющий матрицу 3*3 как массив из 3 объектов типа Vector. Массив создается динамически с использованием оператора new внутри конструктора (как и в случае с Vector).

Определить стандартные операции с матрицами. По крайней мере, необходимо реализовать следующие операции:

  • конструктор копирования

  • оператор присваивания

  • деструктор

  • []

  • *, *=, /, /=(со скаляром)

  • * (c Vector)

  • операторы >> и << для ввода/вывода матрицы через cin/cout

  • transposition() // транспонирование матрицы (вокруг главной диагонали)

  • det() //подсчет детерминанта матрицы.

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

3) Используя созданные классы Vector и Matrix, реализовать утилитный класс для решения уравнений методом Гаусса. Класс должен содержать публичную статическую функцию:

Vector gauss(const Matrix& variables, const Vector& values)

которая решает уравнение вида:

a1x+b1y+c1z=v1

a2x+b2y+c2z=v2

a3x+b3y+c3z=v3

методом исключения Гаусса.

Этот класс должен содержать два специальных статических поля типа Vector с публичным доступом. Первое поле должно быть проинициализировано объектом Vector(FLT_MAX, FLT_MAX, FLT_MAX) (надо подключить <float.h>). Второе поле надо проинициализировать объектом Vector(FLT_MIN, FLT_MIN, FLT_MIN).

Если решение уравнения найти невозможно, то возвращать первый объект. Если решение не единственное, то возвращать второй объект. Таким образом, тот код, который вызывает метод решения уравнения, может сравнить возвращаемое значение с известным статическим полем и понять, что решения нет или их бесконечно много. Псевдокод:

Vector v = … // вызов функции решения уравнения

if (v == …) { // сравниваем с первым статическим полем

cout << “No Solution”;

} else if (v == …) { // сравниваем со вторым статическим полем

cout << “Infinity Set of Solutions”;

} else {

cout << “Solution: \n“ << v.print();

}

4) Создать тестовую глобальную функцию, которая предоставляет консольный интерфейс для ввода параметров: a1-a3, b1-b3, c1-c3, v1-v3 и выдачи результата (используя утилитный класс).

Задание № 2. Наследование и полиморфизм. Простой командный процессор

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

Название

Аргументы

Описание

Примеры

Print

<строка>

Распечатать на экране строку, заданную в аргументе

print Hello World

Eval

<expression>

Вычислить простую арифметическую операцию (+ , - , * , /). Результат вывести на экран. В случае некорректных аргументов вызывать исключение std::invalid_argument

eval 8 / 2

createfile

<file>

Создать файл c именем <file>. Если файл уже существует, то пересоздать. Запросить ввод данных от пользователя (одна строка), записать введенные данные в файл.

createfile test.txt

Exec

<command>

Запустить командную строку, что записана в <command>. Используйте функцию system() из библиотеки "linesystem.h".

exec notepad.exe test.txt

copy test.txt test2.txt

increment

<file>

<file value>

Прочитать содержимое файла <file> и проинтерпретировать его как int. Если в int не конвертируется вызывать исключение std::invalid_argument. Иначе увеличить полученное число на заданное значение и перезаписать в файл. Если число не задано, увеличить на 1.

increment test.txt

increment test.txt 1

viewfile

<file>

Вывести содержимое файла c именем <file> на экран. Если файл не существует, вызывать исключение std::invalid_argument

viewfile test.txt

Пример исходного файла для командного процессора:

print Hello

print I know 2+2=

eval 2+2

print Please input your age:

createfile age.txt

increment age.txt

print It is your age in next year:

viewfile age.txt

print You could check it

exec notepad.exe age.txt

Каждая команда представляется в виде класса, отнаследованного от абстрактного класса Command:

classCommand {

private:

string args;

public:

Command(conststring& s ="") : args(s){};

voidsetArgs(conststring& s) {

args = s;

};

conststring& getArgs()const{

returnargs;

};

friendistream&operator>>(istream& in, Command& c){

returnin >> c.args;

};

friend ostream& operator<<(ostream& out,

const Command& c) {

return out << c.getName() << " " << c.args << endl;

};

virtualconststring& getName()const= 0;

virtualvoidexecute()constthrowstd::invalid_argument)

= 0;

};

Для инициализации и выполнения списка команд необходимо реализовать класс CommandList, который должен содержать следующие методы и операторы:

friendostream&operator<<(ostream& out,

const CommandList& c) {

// Вывести на экран все команды

// Обход списка с помощью класса std:iterator

returnout;

};

friendistream&operator>>(istream& in, CommandList& c) {

// Считать из потока.

// В случае консольного ввода

// выполнение прекращается если строка равна ^D

returnin;

};

voidinit(conststring& file) {

// Считать из файла, используя оператор >>

}

voidexecute()constthrow(std::invalid_argument) {

// Выполнить все команды.

// Обход списка с помощью класса std:iterator

}

Особенности реализации класса CommandList:

  1. Файл считывается построчно с помощью класса для работы с потоками std::ifstream.

  2. Команды хранятся в защищенном поле класса типа std::list.

  3. Обход элементов списка осуществляется с помощью итератора std::iterator.

Пример использования класса CommandList:

CommandList cl = CommandList();

// Чтение из файла:

cl.init("commands.txt");

cl.execute();

// Чтение с консоли:

cin >> cl;

cout << cl;

cl.execute();

Задание № 3. Шаблоны

Переделайте классы Vector и Matrix из задания № 2 так, чтобы можно было создавать векторы и матрицы любых размеров и любых типов (тесты переделайте соответственно). Используйте шаблоны для описания таких векторов. Пример использования:

Vector<int, 5> v1(1,1,1,1,1);

v1[3] = 100;

std:cout<<v1;

Vector<Complex, 3> v2(0,0,0);

Переделайте функцию gauss(), чтобы она так же работала для разных размерностей и типов:

Matrix<double, 5> matrix = … // your initialization

Vector<double, 5> vector = … // your initialization

Vector<double, 5> answer = gauss<double, 5>(matrix, vector);

Вместо статических полей Vector(FLT_MIN, FLT_MIN, FLT_MIN) и Vector(FLT_MAX, FLT_MAX, FLT_MAX) используйте исключения.

Переделайте тестовую глобальную функцию, которая предоставляет консольный интерфейс для решения уравнения Гаусса. Пусть она запрашивает размерность (от 2 до 5) и решает уравнение для типа double.