Алгоритмические языки высокого уровня. Курс лекций
.pdfc.MoveTo(Random(MaxX-40)+20,Random(MaxY-40)+20); Delay(4000)
Until KeyPressed End;
Procedure TApplication.Done; Begin
Dispose(p,Done);
c.Done; CloseGraph
End;
BEGIN Application.Init; Application.Run; Application.Done
END.
Таким образом, любая объектно-ориентированная программа представляет собой совокупность взаимодействующих экземпляров объектов.
7.5.3. Совместимость объектных типов
Основное правило совместимости объектных типов состоит в том, что объекты дочерних типов могут свободно использоваться вместо родительских объектов, но не наоборот, т.е. совместимость расширя- ется по направлению от нижних уровней иерархии к верхним (от по- томков к родителям). При этом любой дочерний тип наследует со- вместимость всех своих родительских типов. Для объектных типов различают совместимость трех видов:
•между экземплярами объектов;
•между указателями на экземпляры объектов;
•между формальными и фактическими параметрами. Экземпляру объекта родительского типа можно присвоить экзем-
пляр любого из его дочерних типов. Недопустимы обратные при- сваивания. В результате выполнения присваивания все информаци- онные поля экземпляра объекта, стоящего слева от оператора при- сваивания, получают значения соответствующих полей экземпляра, стоящего справа.
Указателю на объект родительского типа может быть присвоен указатель на экземпляр объекта дочернего типа. Обратные присваи- вания также недопустимы.
Формальному параметру (параметру-значению или параметру- переменной) данного объектного типа в качестве фактического па-
151
раметра может быть поставлен в соответствие только объект своего же типа, либо любой объект из всех его дочерних типов.
Пример программы
Описание: программа предназначена для перемещения текста по экрану в различных направлениях и его вращению по (против) часо- вой стрелке.
Unit Text_Ex; interface type
Pc=^Cchar; {Класс <Символ>} Cchar=object private
Ch:char; {символ - основное поле} c,x,y,Lx,Ly:{integer;цвет, координаты, размер симво-
ла}
public
Constructor Init(Chn:char;Cn,Xn,Yn:integer); procedure Print;virtual; {вывод символа}
end;
Line=object {Управляющий класс <Линия>} private
M:array[1..100] of Pc;
L:byte; {количество символов – объектов} D:real; {резервное поле - шаг перемещения}
public Constructor
Init(S:string;Cn,Xn,Yn:integer;Dn:real); procedure OutS;virtual; {вывод строки} private
procedure Tie(i:byte;var x,y:integer);virtual; {связывание символов}
procedure Move(i:byte);virtual; {перемещение} end;
LinMovX=object(Line) private
procedure Tie(i:byte;var x,y:integer);virtual; procedure Move(i:byte);virtual;
end;
LinMovY=object(Line) private
procedure Tie(i:byte;var x,y:integer);virtual; procedure Move(i:byte);virtual;
end;
LinMovCir=object(Line) private
Rc,Xc,Yc:integer; {радиус, координаты центра враще-
ния}
V:array[1..100] of real;{угол смещения для каждого сим-
вола}
public
152
Constructor Init(S:string;Cn,Xcn,Ycn:integer;Dn:real);
private
procedure Tie(i:byte;var x,y:integer);virtual; procedure Move(i:byte);virtual;
end; implementation uses crt,graph;
{******************тела методов класса: Cchar*******************}
Constructor Cchar.Init; begin
Ch:=Chn; {символ} C:=Cn; {цвет символа} X:=Xn; Y:=Yn; {начальные кординаты} Lx:=Textwidth(Ch);
Ly:=Textheight(Ch); {размеры символа}
end;
Procedure Cchar.Print; begin
Setcolor(C); OutTextXY(x,y,Ch); end;
{*****************тела методов класса: Line******************* }
Constructor Line.Init; Var i:integer;
begin L:=Length(S); D:=Dn;
for i:=1 to L do begin
New(M[i],Init(S[i],Cn,Xn,Yn)); Tie(i,Xn,Yn); end;
end;
Procedure Line.OutS; Var i,c:integer; begin
for i:=1 to L do begin
c:=M[i]^.C;
M[i]^.C:=Getbkcolor;
M[i]^.Print;
Move(i);
M[i]^.C:=c; M[i]^.Print; end;
end;
Procedure Line.Tie; {абстрактный метод} begin
end;
Procedure Line.Move; {абстрактный метод} begin
end;
{***************тела методов класса: LinMovX******************* }
153
Procedure LinMovX.Tie; begin
X:=M[i]^.X+M[i]^.Lx+2;
Y:=M[i]^.Y;
end;
Procedure LinMovX.Move; begin
M[i]^.X:=round(M[i]^.X+D);
if (D>0)and(M[i]^.X>GetmaxX-M[i]^.Lx) then M[i]^.X:=0;
if (D<0)and(M[i]^.X<0) then M[i]^.X:=GetmaxX- M[i]^.Lx;
end;
{***************тела методов класса: LinMovY*******************}
Procedure LinMovY.Tie; begin
X:=M[i]^.X+M[i]^.Lx; Y:=M[i]^.Y-M[i]^.Ly; end;
Procedure LinMovY.Move; begin
M[i]^.Y:=round(M[i]^.Y+D);
if (D>0)and(M[i]^.Y>GetmaxY-M[i]^.Ly) then M[i]^.Y:=0;
if (D<0)and(M[i]^.Y<0) then M[i]^.Y:=GetmaxY- M[i]^.Ly;
end;
{*************тела методов класса: LinMovCir******************* }
Constructor LinMovCir.Init; Var i,Xn,Yn:integer;
begin
L:=Length(S); Rc:=round((L+1)*2*Textheight(S)/(2*pi)); D:=2*pi/(L+1); {шаг для исходной расстановки символов} V[i]:=pi;
for i:=2 to L do V[i]:=V[i-1]+D; Xc:=Xcn; Yc:=Ycn;
for i:=1 to L do Begin
Tie(i,Xn,Yn); New(M[i],Init(S[i],Cn,Xn,Yn)); end;
D:=Dn; {шаг перемещения } end;
Procedure LinMovCir.Tie; begin X:=round(Rc*cos(V[i])+Xc);
Y:=round(Rc*sin(V[i])+Yc);
end;
Procedure LinMovCir.Move; begin
V[i]:=V[i]+D;
M[i]^.X:=round(Rc*cos(V[i])+Xc);
154
M[i]^.Y:=round(Rc*sin(V[i])+Yc); End ;
end.
{*************тела методов класса: LinMovCir******************}
Program Str_Obj; {основная программа}
uses crt,graph,Text_Ex; {библиотека классов} var
Sx1,Sx2:LinMovX; Sy1,Sy2:LinMovY; Sc1,Sc2:LinMovCir; a,r:integer; d:word;
begin
ClrScr;
Write('Введите задержку:'); readln(d); a:=DETECT; InitGraph(A,r,'');
Setbkcolor(8); Settextstyle(0,0,1); Sx1.Init('Перемещение слева направо',9,245,215,3); Sx2.Init('Перемещение справа налево',13,155,263,-3); Sy1.Init('Перемещение сверху вниз',11,165,250,2); Sy2.Init('Перемещение снизу вверх',12,300,400,-2);
Sc1.Init('Вращение по часовой стрелке',15,GetmaxX div 2,GetmaxY div 2,0.05);
Sc2.Init('Вращение против часовой стрелки',14,GetmaxX div 2,GetmaxY div 2,-0.05);
repeat Sx1.OutS; Sx2.OutS; Sy1.OutS; Sy2.OutS; Sc1.OutS;
Sc2.OutS; delay(d); until keypressed;
closegraph;
end.
155
Библиографический список
Грогоно П. Программирование на языке Паскаль. – М.: Мир,
1982. – 382 с.
Йордан Э. Структурное программирование и проектирование про-
грамм. – М.: Мир, 1979. – 415 с.
Программирование на языке Паскаль / Под ред. О.Ф. Усковой. –
СПб.: Питер, 2002. – 324 с.
Технология программирования: Курс лекций / А.Г. Дьячко, С.В. Костромин, Л.Г. Сергеев, С.Э. Мурадханов. – М.: МИСиС,
1994. – 94 с.
Фаронов В.В. Турбо-Паскаль. Основы Турбо-Паскаля. – М.: МВТУ-ФЕСТО ДИДАКТИК, 1992. – 304 с.
156
Приложение
Системы счисления
Под системой счисления понимается способ представления лю- бого числа с помощью некоторого алфавита символов, называемых цифрами. Системы счисления бывают непозиционные и позицион- ные. Непозиционными системами являются такие системы счисле- ния, в которых каждый символ сохраняет свое значение независимо от места его положения в числе. Примером непозиционной системы счисления является римская система. К недостаткам таких систем относятся наличие большого количества знаков и сложность выпол- нения арифметических операций. Система счисления называется по- зиционной, если одна и та же цифра имеет различное значение, оп- ределяющееся позицией цифры в последовательности цифр, изобра- жающей число. Это значение меняется в однозначной зависимости от позиции, занимаемой цифрой, по некоторому закону. Примером позиционной системы счисления является десятичная система, ис- пользуемая в повседневной жизни. Количество p (различных цифр, употребляемых в позиционной системе) определяет название систе- мы счисления и называется основанием системы счисления – «p».
В десятичной системе используются десять цифр: 0, 1, 2, 3, 4, 5, 6, 7, 8, 9; эта система имеет основанием число десять. Любое число N в позиционной системе счисления с основанием p может быть пред- ставлено в виде полинома от основания p:
N = anpn + an–1pn–1 + ... + a1p + a0 + a–1p–1 + a–2p–2 + ...,
где N – число;
aj – коэффициенты (цифры числа);
p – основание системы счисления (p>1).
Принято представлять числа в виде последовательности цифр:
N= anan–1 ... a1a0 . a–1a–2 ...
Вэтой последовательности точка отделяет целую часть числа от дробной (коэффициенты при положительных степенях, включая нуль, от коэффициентов при отрицательных степенях). Точка опус- кается, если нет отрицательных степеней (число целое).
ВПК применяют позиционные системы счисления с недесятич- ным основанием: двоичную, восьмеричную, шестнадцатеричную. В аппаратной основе ПК лежат двухпозиционные элементы, которые
157
могут находиться только в двух состояниях; одно из них обозначает- ся 0, а другое – 1. Поэтому основной системой счисления, применяе- мой в ПК, является двоичная система.
Двоичная система счисления. Используются две цифры: 0 и 1.
В двоичной системе любое число может быть представлено в виде:
N = bnbn–1 ... b1b0 . b–1b–2 ..., где bj либо 0, либо 1.
Восьмеричная система счисления. Используются восемь цифр: 0, 1, 2, 3, 4, 5, 6, 7. Употребляется в ЭВМ как вспомогательная для записи информации в сокращенном виде. Для представления одной цифры восьмеричной системы используются три двоичных разряда (триада), как показано в табл. П1.
Шестнадцатеричная система счисления. Для изображения чи-
сел употребляются 16 цифр. Первые десять цифр этой системы обо- значаются цифрами от 0 до 9, а старшие шесть цифр – латинскими буквами: 10 – A, 11 – B, 12 – C, 13 – D, 14 – E, 15 – F. Шестнадцате-
ричная система используется для записи информации в сокращенном виде. Для представления одной цифры шестнадцатеричной системы счисления используются четыре двоичных разряда (тетрада).
|
|
|
|
|
Таблица П1 |
|
|
Наиболее важные системы счисления |
|
||||
|
|
|
|
|
|
|
Двоичная |
Восьмерич- |
Десятич- |
|
|
||
ная (ос- |
Шестнадцатеричная |
|||||
(основа- |
ная |
(осно- |
||||
нование |
(основание 16) |
|||||
ние 2) |
вание 8) |
|||||
10) |
|
|
||||
|
|
|
|
|
||
|
|
триады |
|
|
тетрады |
|
0 |
0 |
0 |
0 |
0 |
0 |
|
1 |
1 |
1 |
1 |
1 |
1 |
|
|
2 |
10 |
2 |
2 |
10 |
|
|
3 |
11 |
3 |
3 |
11 |
|
|
4 |
100 |
4 |
4 |
100 |
|
|
5 |
101 |
5 |
5 |
101 |
|
|
6 |
110 |
6 |
6 |
110 |
|
|
7 |
111 |
7 |
7 |
111 |
|
|
|
|
8 |
8 |
1000 |
|
|
|
|
9 |
9 |
1001 |
|
|
|
|
|
A |
1010 |
|
|
|
|
|
B |
1011 |
|
|
|
|
|
C |
1100 |
|
|
|
|
|
D |
1101 |
|
|
|
|
|
E |
1110 |
|
|
|
|
|
F |
1111 |
|
158
Перевод чисел в десятичную систему осуществляется путем со- ставления степенного ряда с основанием той системы, из которой число переводится. Затем подсчитывается значение суммы.
а) Перевести 10101101.1012 → «10» с.с.
Здесь и в дальнейшем при одновременном использовании не- скольких различных систем счисления основание системы, к которой относится число, будем указывать в виде нижнего индекса.
10101101.1012 = 1 27+ 0 26+ 1 25+ 0 24+ 1 23+ 1 22+ 0 21+ 1 20+ + 1 2–1+ 0 2–2+ 1 2–3 = 173.62510
б) Перевести 703.048→ «10» с.с.
703.048 = 7 82+ 0 81+ 3 80+ 0 8–1+ 4 8–2 = 451.062510
в) Перевести B2E.416→ «10» с.с.
B2E.416 = 11 162+ 2 161+ 14 160+ 4 16–1 = 2862.2510
Перевод целых десятичных чисел в недесятичную систему счис-
ления осуществляется последовательным делением десятичного чис- ла на основание той системы, в которую оно переводится, до тех пор, пока не получится частное, меньшее этого основания. Число в новой системе записывается в виде остатков деления, начиная с последне- го.
а) Перевести 18110→ «8» с.с.
Результат: 18110 = 2658 б) Перевести 62210→ «16» с.с.
Результат: 62210 = 26E16
Перевод правильных дробей из десятичной системы счисления в недесятичную. Для перевода правильной десятичной дроби в другую систему эту дробь надо последовательно умножать на основание той системы, в которую она переводится. При этом умножаются только дробные части. Дробь в новой системе записывается в виде целых частей произведений, начиная с первого.
159
Перевести 0.312510→ «8» с.с.
Результат: 0.312510 = 0.248
Замечание: конечной десятичной дроби в другой системе счисле- ния может соответствовать бесконечная (иногда периодическая) дробь. В этом случае количество знаков в представлении дроби в новой системе берется в зависимости от требуемой точности.
Перевести 0.6510→ «2» с.с. Точность 6 знаков.
Результат: 0.6510 ≈ 0.10(1001)2
Для перевода неправильной десятичной дроби в систему счисле- ния с недесятичным основанием необходимо отдельно перевести це- лую часть и отдельно дробную.
Перевести 23.12510→ «2» с.с.
1) Переведем целую часть: |
2) Переведем дробную часть: |
||
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Таким образом: 2310 = 101112; 0.12510 = 0.0012. Результат: 23.12510 = 10111.0012.
Необходимо отметить, что целые числа остаются целыми, а пра- вильные дроби – дробями в любой системе счисления.
Для перевода восьмеричного или шестнадцатеричного числа в двоичную форму достаточно заменить каждую цифру этого числа соответствующим трехразрядным двоичным числом (триадой) или
160
