«Программное обеспечение вычислительной техники и автоматизированных систем»

Вид материалаУчебное пособие

Содержание


Классы определяются с помощью нижеследующих полей
Варианты заданий
Примеры выполнения РГЗ 1
Результаты работы программы
Результаты работы программы
Подобный материал:
1   2   3   4   5   6   7   8   9
^

Классы определяются с помощью нижеследующих полей:

  1. Символьная строка состоит из последовательности символов и длины строки.
  2. Трехмерный вектор состоит из тройки вещественных чисел.
  3. Многочлен от одной переменной задается массивом вещественных коэффициентов и степенью n многочлена.
  4. Рациональное число определяется как пара целых чисел – числитель и знаменатель дроби. Дробь несократима и знаменатель больше нуля.
  5. Неупакованный BCD состоит из массива цифр, знака и длины этого массива.
  6. Битовая строка состоит из массива бит и длины массива. Отрицательные числа представляются аналогично обычным целым числам.
  7. Комплексное число представляется парой вещественных чисел – мнимой и действительной частями комплексного числа.
  8. Проходящая через начало координат в R3 прямая задается ненулевым направляющим вектором. Если направляющие векторы параллельны и не равны нулю, то соответствующие прямые считаются равными.
  9. Прямоугольное окно задается четырьмя числами – координатами левого верхнего и правого нижнего углов.
  10. Плоскость в R3, проходящая через начало координат, определяется ненулевым вектором нормали. Плоскости равны, если векторы нормали параллельны.
  11. Комплексное число в полярных координатах представляется парой чисел, первое из которых неотрицательно и задает абсолютную величину, а второе является аргументом arg, лежащим в пределах 0  arg < 2.
  12. Бинарное отношение определяется с помощью квадратной n x n матрицы, состоящей из нулей и единиц и числа n.



^

Варианты заданий





1. Символьная строка


++

--

int length()

циклический сдвиг вправо,

циклический сдвиг влево,

длина строки

2. Трехмерный вектор


*

+

-

double abs()

векторное произведение

сумма векторов

разность векторов

длина вектора

3. Многочлен от одной

переменной

*

+

-

double cs()

произведение,

сумма,

разность,

свободный коэффициент

4. Прямая в R3,

проходящая через

начало координат

*


==

прямая, перпендикулярная к прямым

проверка на равенство

5. Бинарное отношение

n x n

*

+

int sym()

композиция отношений,

объединение,

проверка на симметричность

6. Трехмерный вектор

+

--

[]

float abs()

сумма векторов

разность векторов

координата с данным номером

длина вектора

7. Битовая строка

<, >

==

long abs()

сравнения величин

проверка на равенство

значение числа, определяемого битовой строкой

8. BCD неупакованный

+, -

*

BCD abs()

сложение и вычитание

умножение

абсолютная величина, возвращается BCD

9. Битовая строка

+

-

BIT abs()

сложение чисел

вычитание чисел

абсолютная величина, возвращается битовая строка

10. Прямоугольное окно

*

+


int S()

пересечение,

наименьшее окно, содержащее данные два окна,

площадь окна

11. Рациональное число

+, -

*

RAT abs()

сумма и разность

произведение

модуль, возвращается рациональное число

12. Символьная строка

=

-

+

int length

присваивание,

обращение,

конкатенация,

длина строки

13. Комплексные числа

+,-

*, /

float abs()

float arg()

сумма и разность

произведение и частное

модуль,

аргумент

14. Рациональное число

*, <, >,

==

float abs()

умножение и сравнения

сравнение на равенство

значение

15. Трехмерные вектора

+,-

*

float abs()

сумма и разность,

векторное произведение

длина вектора

16. Плоскость в R3

*


==

перпендикулярная плоскость к

двум плоскостям,

проверка на равенство

17. Символьная строка


=

<=, >=


присваивание

сравнение относительно лексико-графического отношения порядка

18. Трехмерные векторы

*

+,-,

float abs()

скалярное произведение,

сумма, разность

длина

19. Бинарное отношение

n x n

<=

<

*

int trans()

включение

строгое включение

композиция

проверка на транзитивность

20. Трехмерный вектор


+

-

float abs()

Vol(a,b,c)

сложение векторов

вычитание

длина вектора

смешанное произведение

21. Символьная строка


==

=

<=

int length()

проверка на равенство,

присваивание,

подстрока,

длина строки

22. Бинарное отношение


*

-

<=

int antisym()

пересечение,

обращение (унарная операция)

включение,

проверка на антисимметричность

23. Битовая строка

+, -

++, --

сложение и вычитание

прибавить или вычесть единицу


24. Комплексные числа в полярных координатах

+, -

*

float Re()

float Im()

сумма и разность

произведение

вещественная часть

мнимая часть

25. Битовая строка

&, |, !

double value()

поразрядные логические операции,

значение

26. Битовая строка

>>

<<

[]

double value()

сдвиг вправо,

сдвиг влево,

значение бита с заданным номером

27. Вектор n-мерный

*

+, -

float abs()

скалярное произведение,

сумма и разность

длина вектора

28. Матрица n x n

+, -

*

float norma()

сумма и разность

произведение матриц

норма

29. Битовая строка

+

-

double value()

сумма

минус унарный

30. BCD неупакованный

+, - , /

double abs()

сложение, вычитание и деление

значение



^ Примеры выполнения РГЗ 1


Пример 1


Задание. Определить класс заданного типа. Написать определенные как дружественные функции подпрограммы ввода с клавиатуры и вывода на экран данных, определяющих объекты этого класса. Перегрузить указанные операции и функции с помощью составных функций класса:



Матрица n x n

+, -

*

float norma()

сумма и разность

произведение матриц

норма


Рассмотрим программу с использованием некоторых рассмотренных классов ввода/вывода в сочетании с собственным классом Matrix, в котором собраны матрица и порядок этой матрицы. Элементы-члены в свою очередь являются закрытыми данными класса.

В этой программе мы рассмотрим ввод/вывод объектов собственного класса с использованием классов istream и ostream, функции которых будут определены дружественными для нашего класса. Это достигается перегрузкой операторов функций >> (для объекта cin класса istream) и << (для объекта cout класса ostream), чтобы они поддерживали работу с нашим созданным классом. Помимо этого в программе будут рассмотрены перегрузки таких операторов, как присваивание (=), сложение (+), вычитание (-) и умножение (*). Причем сложение, вычитание и умножение перегружаются дружественными функциями для класса Matrix, а присваивание – функцией-членом нашего класса Matrix, т.к. для этой операции компилятор С++ предусматривает скрытую функцию по умолчанию, если она не определена в явном виде. Еще в нашем классе рассмотрена функция-элемент norma(), которая возвращает норму матрицы типа float, т.е. третью норму матрицы: третья норма матрицы .

Кроме того, в программе предусмотрены два вида конструкторов: конструктор копирования и, следовательно, конструктор по умолчанию; и соответственно для удаления объекта из памяти без завершения программы предусмотрен деструктор.


Примечание. Для ввода и вывода объектов класса Matrix использованы только объекты классов istream и ostream: cin и cout. Функции printf() и scanf() в программе не используются.


Программа


#include

#include

#include


int y;


// Класс матрица

class Matrix

{

private:

// Собственные элементы:


static int size; // Порядок матрицы

int **matrix; // Матрица

public:

// Общедоступные элементы:


Matrix() {} // Конструктор по умолчанию

Matrix(const Matrix &Object); // Конструктор копирования

~Matrix(); // Деструктор


float norma(); // Норма матрицы

Matrix &operator=(const Matrix &Object); // Перегрузка =


Matrix operator+(Matrix &); // Сложение матриц

Matrix operator-(Matrix &); // Вычитание матриц

Matrix operator*(Matrix &); // Перемножение матриц


// Перегрузка оператора << для вывода матрицы

friend ostream &operator<<(ostream &, Matrix &);

// Перегрузка оператора >> для ввода матрицы

friend istream &operator>>(istream &, Matrix &);

};


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

Matrix::Matrix(const Matrix &Object)

{

int i,j;

size = Object.size;

matrix = new int *[size];

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

matrix[i] = new int [size];

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

for (j = 0; j < size; j++)

matrix[i][j] = Object.matrix[i][j];

}


// Деструктор

Matrix::~Matrix()

{

for (int i = 0; i < size; i++)

delete matrix[i];

delete matrix;

}


// Норма матрицы

float Matrix::norma()

{

int i,j;

float tmp = 0;

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

for (j = 0; j < size; j++)

tmp += matrix[i][j] * matrix[i][j];

return sqrt(tmp);

}


// Перегрузка оператора =

Matrix& Matrix::operator=(const Matrix &Object)

{

int i, j;

size = Object.size;

matrix = new int *[size];

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

matrix[i] = new int [size];

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

for (j = 0; j < size; j++)

matrix[i][j] = Object.matrix[i][j];

return *this;

}


// Перегрузка оператора +

Matrix Matrix::operator+(Matrix &fp1)

{

int i, j;

if (size == fp1.size)

{

Matrix fp(fp1);

for (i=0;i
for (j=0;j
fp.matrix[i][j]=matrix[i][j]+fp1.matrix[i][j];

return fp;

}

}


// Перегрузка оператора -

Matrix Matrix::operator-(Matrix &fp1)

{

int i, j;

if (size == fp1.size)

{

Matrix fp(fp1);

for (i = 0; i < fp.size; i++)

for (j = 0; j < fp.size; j++)

fp.matrix[i][j] = matrix[i][j] - fp1.matrix[i][j];

return fp;

}

}


// Перегрузка оператора *

Matrix Matrix::operator*(Matrix &fp1)

{

int i, j, k, sum;

if (size == fp1.size)

{

Matrix fp(fp1);

for(i = 0; i < fp.size; i++)

for(j = 0; j < fp.size; j++)

{

sum = 0;

for (k = 0; k < fp.size; k++)

sum += matrix[i][k] * fp1.matrix[k][j];

fp.matrix[i][j]=sum;

}

return fp;

}

}


// Перегрузка оператора >>

istream &operator>>(istream &fi, Matrix &fp)

{

int i, j;

fp.matrix = new int *[fp.size];

for (i = 0; i < fp.size; i++)

fp.matrix[i] = new int [fp.size];


for (i = 0; i < fp.size; i++)

for (j = 0; j < fp.size; j++)

{

gotoxy((j + 1) * 4, y + i + 2);

fi >> fp.matrix[i][j];

}

y += i + 2 /*- 1*/;

return fi;

}


// Перегрузка оператора <<

ostream &operator<<(ostream &fo, Matrix &fp)

{

int i, j;

for (i = 0; i < fp.size; i++)

for (j = 0; j < fp.size; j++)

{

gotoxy((j + 1) * 4, y + i + 2);

fo << fp.matrix[i][j];

}

y += i + 2 /*- 1*/;

return fo;

}


int Matrix::size = 2;


void main()

{

clrscr();

Matrix pr1, pr2;

cout << "Введите матрицу A ->\n ";

cin >> pr1;

cout << "\nВведите матрицу B ->\n ";

cin >> pr2;

cout << "\nA+B="<<(pr1+pr2);

cout << "\n\nA-B="<<(pr1-pr2);

cout << "\n\nA*B="<<(pr1*pr2);

pr1 = pr2;

cout << "\nНорма матрицы B = " << pr1.norma();

getch();

}


Результаты работы программы


Введите матрицу A ->

1 10

20 32

Введите матрицу B ->

-20 43
  1. -45


A+B=

-19 53

20 -13


A-B=

21 -33

20 77


A*B=

-20 -407

-400 -580


Норма матрицы B = 65.375839

Пример 2



Задание. Определить класс заданного типа. Написать определенные как дружественные функции подпрограммы ввода с клавиатуры и вывода на экран данных, определяющих объекты этого класса. Перегрузить указанные операции и функции с помощью составных функций класса:



Комплексные числа

+, -

*, /

float abs()


Рассмотрим программу с использованием некоторых рассмотренных классов ввода/вывода в сочетании с собственным классом Complex, который включает действительную (real) и мнимую (image) часть. Элементы-члены в свою очередь являются закрытыми данными класса.

В этой программе мы рассмотрим вывод объектов собственного класса с использованием класса ostream, функция которого будет определена дружественной для нашего класса. Это достигается перегрузкой операторов функций << (для объекта cout класса ostream), чтобы они поддерживали работу с нашим созданным классом. Помимо этого в программе будут рассмотрены перегрузки таких операторов, как сложение (+), вычитание (-), умножение (*) и деление (/). Кроме того, в программе предусмотрены конструктор по умолчанию; и соответственно для удаления объекта из памяти без завершения программы предусмотрен деструктор. Еще в нашем классе рассмотрена функция-элемент abs(), которая возвращает модуль комплексного числа типа float, т.е. .

Программа



#include

#include

#include


class Complex

{

private:

double real; // Действительная часть

double image; // Мнимая часть

public:

Complex() {}; // Конструктор по умолчанию

Complex(double r) { real = r; image = 0; } // Конструктор

Complex(double r, double i) { real = r, image = i; } // Конструктор

~Complex() {} // Деструктор

float abs() // Модуль комплексного числа

{

return sqrt(real * real - image * image);

}


Complex operator+(Complex &); // Перегрузка оператора сложения

Complex operator-(Complex &); // Перегрузка оператора вычитания

Complex operator*(Complex &); // Перегрузка оператора умножения

Complex operator/(Complex &); // Перегрузка оператора деления


// Перегрузка функции-оператора << для вывода класса Complex

friend ostream &operator<<(ostream &, Complex &);


// Перегрузка функции-оператора >> для ввода класса Complex

friend istream &operator>>(istream &, Complex &);

};


// Перегрузка +

Complex Complex::operator+(Complex &fp1)

{

fp1.real = real + fp1.real;

fp1.image = image + fp1.image;

return fp1;

}


// Перегрузка -

Complex Complex::operator-(Complex &fp1)

{

fp1.real = real - fp1.real;

fp1.image = image - fp1.image;

return fp1;

}


// Перегрузка *

Complex Complex::operator*(Complex &fp1)

{

double i, j;

i = real * fp1.real - image * fp1.image;

j = real * fp1.image + fp1.real * image;

fp1.real = i;

fp1.image = j;

return fp1;

}


// Перегрузка /

Complex Complex::operator/(Complex &fp1)

{

double k, i, j;

k = fp1.real * fp1.real + fp1.image * fp1.image;

i = (real * fp1.real + image * fp1.image) / k;

j = (fp1.real * image - real * fp1.image) / k;

fp1.real = i;

fp1.image = j;

return fp1;

}


// Перегрузка оператора <<

ostream &operator<< (ostream &fo, Complex &fp)

{

if (fp.image < 0) fo << fp.real << "+i(" << fp.image << ")\n";

else fo << fp.real << "+i" << fp.image << "\n";


return fo;

}


// Перегрузка оператора >>

istream &operator>>(istream &fi, Complex &fp)

{

cout << "Введите действительную часть: ";

fi >> fp.real;

cout << "Введите мнимую часть: ";

fi >> fp.image;

return fi;

}


void main()

{

clrscr();


// Комплексные числа

Complex c1, c2, c3, c4, c5;


// Ввод комплексных чисел

cin >> c1;

cin >> c2;

cin >> c3;

cin >> c4;

cin >> c5;


// Вывод комплексных чисел

cout << "\nc1 = " << c1;

cout << "c2 = " << c2;

cout << "c3 = " << c3;

cout << "c4 = " << c4;

cout << "c5 = " << c5 << '\n';


cout << "Модуль c1: " << c1.abs() << "\n\n";


// Вывод результатов операций

cout << "c1 + c2 = " << (c1 + c2);

cout << "c1 - c3 = " << (c1 - c3);

cout << "c1 * c4 = " << (c1 * c4);

cout << "c1 / c5 = " << (c1 / c5);


getch();

}
^
Результаты работы программы


Введите действительную часть: 9

Введите мнимую часть: 8

Введите действительную часть: 7

Введите мнимую часть: 6

Введите действительную часть: 5

Введите мнимую часть: 4

Введите действительную часть: 3

Введите мнимую часть: 2

Введите действительную часть: 1

Введите мнимую часть: 2


c1 = 9+i8

c2 = 7+i6

c3 = 5+i4

c4 = 3+i2

c5 = 1+i2


Модуль c1: 4.123106


c1 + c2 = 16+i14

c1 - c3 = 4+i4

c1 * c4 = 11+i42

c1 / c5 = 5+i(-2)

Пример 3


Задание. Определить класс заданного типа. Написать определенные как дружественные функции подпрограммы ввода с клавиатуры и вывода на экран данных, определяющих объекты этого класса. Перегрузить указанные операции и функции с помощью составных функций класса:



Неупакованный BCD

+, -

=



Рассмотрим программу с использованием некоторых рассмотренных классов ввода/вывода в сочетании с собственным классом LongBCD, который состоит из последовательности цифр. Элементы-члены в свою очередь являются закрытыми данными класса.

Операция сложения чисел складывает и вычитает цифры, начиная с младших разрядов.

Числа выводятся с помощью стандартных функций

Программа



#include

#include

#include

#include


//Числа хранятся в формате "младший разряд первым",

//Поддержка отрицательных чисел отсутствует


//Минимальный размер выделяемой памяти под хранение BCD числа

#define MINBCDSIZE 4


// Класс BCD-числа

class LongBCD

{

private:

char * data; // BCD-число

int size; // Его размер


// Функция увеличения области данных с их сохранением

void extend(int newsize)

{

char *nd = new char [newsize];

memset(nd, '0', newsize);

memcpy(nd, data, size);

size = newsize;

delete data;

data = nd;

}


// Установка значения i-го разряда области данных BCD-числа

void set(int i, char dig)

{

if (i >= size)

extend(i + 1);

data[i] = dig;

}


// Обнуление области данных BCD-числа, начиная с i-го разряда

void zero(int i);

// Установка значения BCD-числа на основании другого BCD-числа

void setvalue(LongBCD & n);

// Суммирование (+=)

void add(LongBCD & n);

// Вычитание (-=)

void sub(LongBCD & n);


public:

// Конструкторы

LongBCD();

LongBCD(long n);

// Деструктор

~LongBCD() {if (data) free(data);}


// Установка значения BCD-числа на основании long

void setvalue(long n);


// Перегрузка оператора присваивания

LongBCD & operator = (long n) {setvalue(n); return *this;}

LongBCD & operator = (LongBCD & n) {setvalue(n); return *this;}


// Перегрузка операций + и -

friend LongBCD operator + (LongBCD &, LongBCD &);

friend LongBCD operator - (LongBCD &, LongBCD &);


// Функция вывода BCD-числа на экран

void show(void);

};


// Суммирование (+=)

void LongBCD::add(LongBCD & n)

{

int maxl = n.size;

int i, carry = 0;


// Проверка наличия достаточного количества памяти

if (maxl >= size) extend(maxl + 1);


// Цикл по всем разрядам, начиная с младшего

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

{

int res = (data[i] - '0') + (n.data[i] - '0') + carry;


// Учет переноса

if (res > 9)

{

res -= 10;

carry = 1;

}

else carry = 0;


set(i, '0' + res);

}


if (carry) set(maxl, '1');

}


// Вычитание (-=)

void LongBCD::sub(LongBCD & n)

{

int maxl = n.size;

int i, carry = 0;


// Проверка наличия достаточного количества памяти

if (maxl >= size) extend(maxl + 1);


// Цикл по всем разрядам, начиная с младшего

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

{

int res = (data[i] - '0') - (n.data[i] - '0') - carry;


// Учет заема

if (res < 0)

{

res += 10;

carry = 1;

}

else carry = 0;


set(i, '0' + res);

}

}


// Обнуление области данных BCD-числа, начиная с i-го разряда

void LongBCD::zero(int i)

{

while(i < size) data[i++] = '0';

}


// Установка значения BCD-числа на основании long

void LongBCD::setvalue(long n)

{

int i = 0;


while (n != 0)

{

set(i, '0' + (n % 10));

n /= 10;

i++;

}


zero(i);

}


// Установка значения BCD-числа на основании другого BCD-числа

void LongBCD::setvalue(LongBCD & n)

{

int i;

for (i = 0; i < n.size; i++) set(i, n.data[i]);

zero(i);

}


// Функция вывода BCD-числа на экран

void LongBCD::show(void)

{

int i = size;

while((i != 0) && (data[i-1] == '0')) i--;


if (i == 0)

putchar('0');

else

while (i != 0) {

i--;

putchar(data[i]);

}


puts("");

}


// Конструктор создает число со значеним 0

LongBCD::LongBCD()

{

data = new char[MINBCDSIZE];

size = MINBCDSIZE;

zero(0);

}


// Конструктор создает число со значеним, определяемым переменной

LongBCD::LongBCD(long n)

{

data = new char[MINBCDSIZE];

size = MINBCDSIZE;

setvalue(n);

}


// Перегрузка операции +

LongBCD operator + (LongBCD & a, LongBCD & b)

{

LongBCD * temp = new LongBCD;

*temp = a;

temp->add(b);

return * temp;

}


// Перегрузка операции -

LongBCD operator - (LongBCD & a, LongBCD & b)

{

LongBCD * temp = new LongBCD;

*temp = a;

temp->sub(b);

return * temp;

}


void main(void)

{

clrscr();

LongBCD A, B, C;


long temp;

cout << "Введите BCD-число A: ";

cin >> temp;

A.setvalue(temp);


cout << "Введите BCD-число B: ";

cin >> temp;

B.setvalue(temp);


cout << "\nA = "; A.show();

cout << "\nB = "; B.show();

cout << "\nA+B = "; C=A+B; C.show();

cout << "\nA-B = "; C=A-B; C.show();


getch();

}

^
Результаты работы программы


Введите BCD-число A: 12345

Введите BCD-число B: 324

A = 12345

B = 324

A+B = 12669

A-B = 12021


РАСЧЕТНО-ГРАФИЧЕСКОЕ ЗАДАНИЕ 2


Шаблоны функций и классов

Задание
  • Написать параметризованную подпрограмму сортировки указанным методом. Отладить ее на целых числах и числах с плавающей точкой.
  • Определить класс объектов массива, предназначенного для сортировки. Перегрузить для него операцию присваивания и операции сравнения <, <=, ==, >=, >.
  • Написать программу, сортирующую массив объектов построенного класса с помощью написанной параметризованной подпрограммы.