Меню
  Список тем
  Поиск
Полезная информация
  Краткие содержания
  Словари и энциклопедии
  Классическая литература
Заказ книг и дисков по обучению
  Учебники, словари (labirint.ru)
  Учебная литература (Читай-город.ru)
  Учебная литература (book24.ru)
  Учебная литература (Буквоед.ru)
  Технические и естественные науки (labirint.ru)
  Технические и естественные науки (Читай-город.ru)
  Общественные и гуманитарные науки (labirint.ru)
  Общественные и гуманитарные науки (Читай-город.ru)
  Медицина (labirint.ru)
  Медицина (Читай-город.ru)
  Иностранные языки (labirint.ru)
  Иностранные языки (Читай-город.ru)
  Иностранные языки (Буквоед.ru)
  Искусство. Культура (labirint.ru)
  Искусство. Культура (Читай-город.ru)
  Экономика. Бизнес. Право (labirint.ru)
  Экономика. Бизнес. Право (Читай-город.ru)
  Экономика. Бизнес. Право (book24.ru)
  Экономика. Бизнес. Право (Буквоед.ru)
  Эзотерика и религия (labirint.ru)
  Эзотерика и религия (Читай-город.ru)
  Наука, увлечения, домоводство (book24.ru)
  Наука, увлечения, домоводство (Буквоед.ru)
  Для дома, увлечения (labirint.ru)
  Для дома, увлечения (Читай-город.ru)
  Для детей (labirint.ru)
  Для детей (Читай-город.ru)
  Для детей (book24.ru)
  Компакт-диски (labirint.ru)
  Художественная литература (labirint.ru)
  Художественная литература (Читай-город.ru)
  Художественная литература (Book24.ru)
  Художественная литература (Буквоед)
Реклама
Разное
  Отправить сообщение администрации сайта
  Соглашение на обработку персональных данных
Другие наши сайты
Приглашаем посетить
  Философия (philosophy.niv.ru)

   

Законченная программа

Законченная программа

Администратор экрана: подпрограммы низкого уровня и структуры данных, определяющие экран; он ведает только точками и прямыми линиями;

Библиотека фигур: набор определений основных фигур вроде прямоугольника и круга и стандартные программы для работы с ними; и

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

у разработчиков нижнего уровня не будет точного представления, для чего их код в конечном счете будет использоваться. Это отражено в приводимом примере. Чтобы пример был короче, графическая библиотека предоставляет только весьма ограниченный сервис, а сама прикладная программа очень проста. Чтобы читатель смог испытать программу, даже если у него нет совсем никаких графических средств, используется чрезвычайно простая концепция экрана. Не должно составить труда заменить эту экранную часть программы чем-нибудь подходящим, не изменяя код библиотеки фигур и прикладной программы.

Администратор Экрана

Вначале было намерение написать администратор экрана на C (а не на C++), чтобы подчеркнуть разделение уровней реализации. Это оказалось слишком утомительным, поэтому пришлось пойти на компромисс: используется стиль C (нет функций членов, виртуальных функций, определяемых пользователем операций и т. п.), однако применяются конструкторы, надлежащим образом описываются и проверяются параметры функций и т. д. Оглядываясь назад, можно сказать, что администратор экрана очень похож на C программу, которую потом модифицировали, чтобы воспользоваться средствами C++ не переписывая все полностью.

Экран представляется как двумерный массив символов, работу с которым осуществляют функции putpoint() и putline(), использующие при ссылке на экран структуру point:

// файл screen. h

const XMAX=40, YMAX=24;

struct point {

int x,y;

point() {}

point(int a, int b) { x=a; y=b; }

};

overload putpoint;

inline void putpoint(point p) { putpoint(p. x,p. y); }

inline void putline(point a, point b)

{ putline(a. x,a. y,b. x,b. y); }

extern void screenrefresh();

extern void screenclear();

#include

Перед первым использованием функции put экран надо инициализировать с помощью screeninit(), а изменения в структуре данных экрана отображаются на экране только после вызова screenrefresh(). Как увидит пользователь, это "обновление" ("refresh") осуществляется просто посредством печати новой копии экрана под его предыдущим вариантом. Вот функции и определения данных для экрана:

#include "screen. h"

#include

"*", white=" " };

char screen[XMAX][YNAX];

void screeninit()

{

for (int y=0; y=a a<=b) y0 += dy, eps -= twoa;

}

}

Предоставляются функции для очистки экрана и его обновления:

void screenclear() { screeninit(); } // очистка

void screenrefresh() // обновление

{

for (int y=YMAX-1; 0<=y; y--) { // сверхувниз

for (int x=0; x

Библиотека Фигур

Нам нужно определить общее понятие фигуры (shape). Это надо сделать таким образом, чтобы оно использовалось (как базовый класс) всеми конкретными фигурами (например, кругами и квадратами), и так, чтобы любой фигурой можно было манипулировать исключительно через интерфейс, предоставляемый классом shape:

struct shape {

shape() { shapelist. append(this); }

virtual point north() { return point(0,0); } // север

virtual point south() { return point(0,0); } // юг

virtual point east() { return point(0,0); } // восток

virtual point neast() { return point(0,0); } // северо-восток

virtual point seast() { return point(0,0); } // юго-восток

virtual void draw() {}; // нарисовать

};

и эти точки перечисляются после точек на компасе (сторон света). Каждая конкретная фигура определяет свой смысл этих точек, и каждая определяет способ, которым она рисуется. Для экономии места здесь на самом деле определяются только необходимые в этом примере стороны света. Конструктор shape::shape() добавляет фигуру в список фигур shapelist. Этот список является gslist, то есть, одним из вариантов обобщенного односвязанного списка, определенного в #7. 3. 5. Он и соответствующий итератор были сделаны так:

typedef shape* sp;

поэтому shapelist можно описать так:

shapelst shapelist;

Линию можно построить либо по двум точкам, либо по точке и целому. В последнем случае создается горизонтальная линия, длину которой определяет целое. Знак целого указывает, каким концом является точка: левым или правым. Вот определение:

class line : public shape {

/*

линия из "w" в "e"

north() определяется как ``выше центра

и на север как до самой северной точки""

*/

point w,e;

public:

point north()

{ return point((w. x+e. x)/2,e. ydraw();

screenrefresh();

}

И вот, наконец, настоящая сервисная функция (утилита). Она кладет одну фигуру на верх другой, задавая, что south() одной должен быть сразу над north() другой:

{

point n = p->north();

point s = q->south();

>move(n. x-s. x,n. y-s. y+1);

}

и откомпилированный вариант определений функций. И у вас все равно остается возможность определять новые фигуры и использовать для ваших собственных фигур сервисные функции.

Прикладная Программа

Прикладная программа чрезвычайно проста. Определяется новая фигура myshape (на печати она немного похожа на рожицу), а потом пишется главная программа, которая надевает на нее шляпу. Вначалеописание myshape:

#include "shape. h"

class myshape : public rectangle {

line* leye; // левыйглаз

line* mouth; // рот

public:

myshape(point, point);

void move(int, int);

};

Глаза и рот - отдельные и независимые объекты, которые создает конструктор myshape:

myshape::myshape(point a, point b) : (a,b)

{

int ll = neast(). x-swest(). x+1;

leye = new line(

point(swest(). x+2,swest(). y+hh*3/4),2);

reye = new line(

point(swest(). x+ll-4,swest(). y+hh*3/4),2);

mouth = new line(

point(swest(). x+2,swest(). y+hh/4),ll-4);

}

Объекты глаза и рот порознь рисуются заново функцией shaperefresh(), и в принципе могут обрабатываться независимо из объекта myshape, которому они принадлежат. Это один способ определять средства для иерархически построенных объектов вроде myshape. Другой способ демонстрируется на примере носа. Никакой нос не определяется, его просто добавляет к картинке функция draw():

void myshape::draw()

{

rectangle::draw();

putpoint(point(

(swest(). x+neast(). x)/2,(swest(). y+neast(). y)/2));

}

myshape передвигается посредством перемещения базового прямоугольника rectangle и вторичных объектов leye, reye и mouth (левого глаза, правого глаза и рта):

{

rectangle::move();

leye->move(a,b);

reye->move(a,b);

mouth->move(a,b);

}

Мы можем, наконец, построить несколько фигур и немного их подвигать:

main()

{

shape* p2 = new line(point(0,15),17);

shape* p3 = new myshape(point(15,10),point(27,18));

shaperefresh();

p3->move(-10,-10);

stack(p2,p3);

stack(p1,p2);

shaperefresh();

return 0;

}

Еще раз обратите внимание, как функции вроде shaperefresh() и stack() манипулируют объектами типов, определяемых гораздо позже, чем были написаны (и, может быть, откомпилированы) сами эти функции.

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

***********

* *

* *

* *

* *

* *

* *

* *

* *

* *

***********

* *

* *

* * *

* *

* *

*************