Алгоритмические языки высокого уровня. Курс лекций
.pdf
CHR(I) дает символ, стоящий под номером I в упорядоченном множестве символов. CHR(66)=’B’, CHR(57)=’9’.
CHR(ORD(S))=S и ORD(CHR(I))=I.
Над переменными символьного типа определены операции отно- шения. Отношение C1<C2 истинно когда ORD(C1)<ORD(C2). К аргументам символьного типа применимы также функции: PRED(S) и SUCC(S). Функция PRED(S) дает предыдущий символ, a функ-
ция SUCC(S) – следующий. PRED(‘B’)=’A’ SUCC(‘9’)=’:’. Справедливы равенства: PRED(S)=CHR(ORD(S)-1),
SUCC(S)=CHR(ORD(S)+1).
IBM-совместимые компьютеры обрабатывают 256 различных символов, каждый из которых занимает один байт. Соответствие символов и байтов задается таблицей кодировки, в которой для ка- ждого символа указывается соответствующий байт.
Символы с кодами от 0 до 127 построены по стандарту ASCII
(American Standard Code for Information Interchange – Американский стандартный код обмена информацией, читается «аски»). Вторая по- ловина таблицы (коды 128...255) в нашей стране содержит русские буквы (кириллицу) и символы псевдографики.
Таблица 4.3
Кодировка символов
Коды 0...127
Коды 128...255
(кодировка ASCII)
(модифицированный альтернативный вариант)
51
Для того чтобы определить по этим таблицам код того или иного символа, нужно сложить номер строки с номером столбца, в которых он расположен. Так, код цифры 5 равен 05+048 = 053.
Библиотека CRT позволяет менять цвета и яркость экрана, произ- водить его очистку, управлять звуковым генератором компьютера. Подключение модуля CRT производится директивой USES CRT, ко- торая указывается в разделе описаний. CRT – аббревиатура, озна- чающая «Электронно-лучевая трубка».
Таблица 4.4
Коды настройки цветов в модуле CRT Turbo Pascal
Константа |
Число |
Цвет |
Процедуры |
|
Black |
0 |
Черный |
TextColor, |
|
TextBackGround |
||||
|
|
|
||
Blue |
1 |
Синий |
TextColor, |
|
TextBackGround |
||||
|
|
|
||
Green |
2 |
Зеленый |
TextColor, |
|
TextBackGround |
||||
|
|
|
||
Cyan |
3 |
Голубой |
TextColor, |
|
TextBackGround |
||||
|
|
|
||
Red |
4 |
Красный |
TextColor, |
|
TextBackGround |
||||
|
|
|
||
Magenta |
5 |
Фиолетовый |
TextColor, |
|
TextBackGround |
||||
|
|
|
||
Brown |
6 |
Коричневый |
TextColor, |
|
TextBackGround |
||||
|
|
|
||
LightGray |
7 |
Ярко-серый |
TextColor, |
|
TextBackGround |
||||
|
|
|
||
DarkGray |
8 |
Темно-серый |
TextColor |
|
LightBlue |
9 |
Ярко-синий |
TextColor |
|
LightGreen |
10 |
Ярко-зеленый |
TextColor |
|
LightCyan |
11 |
Ярко-голубой |
TextColor |
|
LightRed |
12 |
Ярко-красный |
TextColor |
|
LightMagenta |
13 |
Ярко-фиолетовый |
TextColor |
|
Yellow |
14 |
Желтый |
TextColor |
|
White |
15 |
Белый |
TextColor |
|
Blink |
128 |
Мерцание |
TextColor |
|
(как слагаемое) |
||||
|
|
|
Основные процедуры/функции модуля CRT
Uses CRT – подключение модуля CRT; TextColor – устанавливает цвет символов;
52
TextBackGround – устанавливает цвет фона (только 8 неярких цветов);
HighVideo – устанавливает включение яркости; LowVideo – устанавливает выбор низкой яркости;
NormVideo – восстановление того цвета, который был на момент начала работы программы;
ClrScr – производит очистку экрана;
ReadKey – обеспечивает задержку изображения и выход из про- граммы при нажатии любой клавиши ([ESC], [Enter], [Пробел]);
Sound(1000) – включение звукового сигнала частотой 1000 Гц; Sound(1500) – включение звукового сигнала частотой 1500 Гц; Delay(1000) – установка (задержка) звучания на время 1 с
(1000 мс);
Delay(2000) – установка (задержка) звучания на время 2 с; NoSound – отключение звукового сигнала.
Пример подключения модуля CRT
Uses CRT; begin
TextColor(14); {Задаёт желтые символы текста} TextBackGround(5); {Задаёт фиолетовый фон} HighVideo; {Устанавливает включение яркости} ClrScr; {Очищает экран}
TextColor(14+128); {Задаёт мерцание символов желтого цвета} end;
Перечисляемый тип задается перечислением значений, которые он может получать. Эти значения образуют упорядоченное множест- во и являются константами этого типа. Каждое значение именуется некоторым идентификатором и располагается в списке, обрамленном круглыми скобками. Упорядоченность элементов перечисляемого типа определяется порядком их следования. Самый левый имеет ми- нимальное значение (значение функции ORD для него равно 0), а наиболее правый – максимальное.
Type week = (m, w, s, san ); colors =(red, white, blue);
Переменные любого перечисляемого типа можно объявлять без предварительного описания этого типа: Var col: (black,
white, green);
Соответствие между значениями перечисляемого типа и порядко- выми номерами этих значений устанавливается порядком перечисле-
53
ния: первое значение в списке получает порядковый номер 0, вто- рое – 1 и т.д. Максимальная мощность перечисляемого типа состав- ляет 65536 значений, поэтому фактически перечисляемый тип зада- ет некоторое подмножество целого типа WORD и может рассматри- ваться как объявление группы целочисленных констант со значения- ми 0, 1 и т.д. Использование перечисляемых типов повышает надеж- ность программ благодаря возможности контроля тех значений, ко- торые получают соответствующие переменные. Приведем пример задания перечисляемых типов.
Type
colors=(black,red,white); {ord(black)=0, ord(white)=2} ordenal=(one,two,three); {ord(one)=0, ord(three)=2} days=(monday,tuesday,Wednesday);
{ord(monday)=0,ord(Wednesday)=2} Var
col :colors; num :ordenal; day : days; begin
col:=black;
num:=succ(two);
day:=pred(tuesday);
col:=one;
col:=colors(0);
col:= one; day:= black; col:= 0; { недопустимо } end;
Между значениями перечисляемого типа и множеством целых чи- сел существует однозначное соответствие, задаваемое функцией ORD(X). В Pascal допускается и обратное преобразование: любое выражение типа WORD можно преобразовать в значение перечис- ляемого типа, если только значение целочисленного выражения не превышает мощность перечисляемого типа. Такое преобразование достигается применением автоматически объявляемой функции с именем перечисляемого типа (col:=one; col:=colors(0)).
Пример программы
Описание: в детском саду на Новый год каждому ребенку в груп- пе из 30 человек подарили подарки. Подарки вводятся в произволь- ном порядке (отделяются запятой), признаком окончания является точка. Вид игрушек: {Заяц = i2 Робот = ii3 Мяч = iii4 Кукла = iiii5 Машина = iiiii6}. Необходимо определить, каких игрушек подарили больше всего.
Program New Year;
Uses crt;
54
Const N=30; Sb=’_____’;
Type igr = (i2, ii3, iii4, iiii5, iiiii6); nameIgr=array[1..6] of char;
Var podar : array[1..N] of nameIgr; kol : array[igr] of 0..N;
name : nameIgr; i_1, ind : Igr; i, j, max: 1..N; sym:char;
begin
clrscr;
for i:=1 to N do begin
name:=sb; j:=1; read(sym);
while (sym<>’,’) and (sym<>’.’) do begin
name[j]:=sym; j:=j+1; read(sym);
end;
podar[i]:=name; read(sym); if sym=’.’ then break; readln;
end;
for ind:=i2 to iiiii6 do kol[ind]:=0;
for i_1:=i2 to iiiii6 do for i:=1 to N do
begin name:=podar[i];
if name=’Заяц__’ then ind:=i2; if name=’Робот__’ then ind:=ii3; if name=’Мяч__’ then ind:=iii4;
if name=’Кукла__’ then ind:=iiii5; if name=’Машина__’ then ind:=iiiii6; kol [ind]:=kol[ind]+1;
end;
max:=kol[i2]; i_1:=i2; for ind:=i2 to iiiii6 do if kol[ind]>max then begin
max:=kol[ind]; i_1:=ind; end;
gotoxy(1,25); write(‘больше всего игрушек_’); case i_1 of
i2:write(‘Заяц’); ii3:write(‘Робот’); iii4:write(‘Мяч’); iiii5:write(‘Кукла’); iiiii6:write(‘Машина’); end;
write(‘max- ’,max);
end.
55
Тип-диапазон – подмножества своего базового типа, в качестве которого может выступать любой порядковый тип, кроме типа диа- пазон (этот тип часто используется в операторе case). Тип-диапазон задается границами своих значений внутри базового типа: <Тип-
диапазон>:<минимальное значение>...<максимальное значение>.
При определении типа-диапазона нужно соблюдать следующие правила:
•символы <..> рассматриваются, как один символ (между ними недопустимы пробелы);
•левая граница диапазона не должна превышать его правую гра- ницу. Тип-диапазон наследует все свойства своего базового типа, но
сограничениями, связанными с его меньшей мощностью.
Var a: 1..7; { подмножество целого типа }
b:'0'..'8'; { подмножество символьного типа }
c:'a'..'k' ; { подмножество символьного типа }
Type b1 = (a1, a2, a3, a4); days = (mo,tu,we,th,fr,sa,su); WeekEnd = sa .. su;
Var b5: a2..a4; { подмножество перечисляемого типа } w : WeekEnd;
w := sa; - ORD(W) вернет значение 5 (PRED(W) приведет к ошибке)
НIGН(Х) – возвращает максимальное значение типа-диапазона; LOW(X) – возвращает минимальное значение типа-диапазона.
var
k: Integer; begin
WriteLn(Low(k),'.',High(k))
{программа выведет на экран строку: -32768...32767} end.
4.1.2.Вещественные типы
Вотличие от порядковых типов, значения которых всегда сопос- тавляются с рядом целых чисел и, следовательно, представляются в ПК абсолютно точно, значения вещественных типов определяют произвольное число лишь с некоторой конечной точностью, завися- щей от внутреннего формата вещественного числа. Диапазон воз- можных значений вещественных типов зависит от их внутреннего представления, которое может занимать от четырех до десяти байт.
56
|
|
|
Таблица 4.5 |
|
Вещественные типы данных и диапазон значений |
||
|
|
|
|
Длина, |
Название |
0 |
Диапазон десятичного порядка |
байт |
|
|
|
4 |
SINGLE |
7...8 |
-39...+38 |
6 |
REAL |
11...12 |
-39...+38 |
8 |
DOUBLE |
15...16 |
-324...+308 |
10 |
EXTENDED |
19...20 |
-4951...+4932 |
8 |
COMP |
19...20 |
-2*1063+1...+2*63-1 |
Вещественное число в Pascal занимает от 4 до 10 смежных байт и имеет следующую структуру в памяти ПК:
s |
e |
m |
s – знаковый разряд числа;
е – экспоненциальная часть; содержит двоичный порядок; m – мантисса числа.
Мантисса m имеет длину от 23 (для SINGLE) до 63 (для EXTENDED) двоичных разрядов, что и обеспечивает точность 7...8 для SINGLE и 19...20 для EXTENDED десятичных цифр. Деся- тичная точка (запятая) подразумевается перед левым (старшим) раз- рядом мантиссы, но при действиях с числом ее положение сдвигает- ся влево или вправо в соответствии с двоичным порядком числа, хранящимся в экспоненциальной части, поэтому действия над веще- ственными числами называют арифметикой с плавающей точкой (за-
пятой). Доступ в Pascal к типам SINGLE, DOUBLE и EXTENDED
возможен только при особых режимах компиляции. Дело в том, что эти типы рассчитаны на аппаратную поддержку арифметики с пла- вающей точкой и для их эффективного использования в состав ПК должен входить арифметический сопроцессор. Компилятор Turbo Pascal позволяет создавать программы, работающие на любых ПК (с сопроцессором или без него) и использующие любые вещественные типы (арифметический сопроцессор всегда обрабатывает числа в формате EXTENDED, а три других вещественных типа в этом слу- чае получаются простым усечением результатов до нужных размеров и применяются в основном для экономии памяти). В некоторых слу- чаях бывает необходимо отключить автоконтроль. Для этого перед запуском Turbo Pascal следует дать такую команду DOS: set 87=N. Команда set 87=Y включает автоконтроль (эта ко- манда активна по умолчанию).
57
Если «машинное эпсилон» вычисляется с помощью программы
{$N+,E+} type
RealType = Real: var
epsilon : RealType; begin
epsilon := 1;
while 1+epsilon/2 > 1 do epsilon := epsilon/2;
WriteLn(epsilon)
end.
то независимо от объявления типа REALTYPE
(SINGLE,REAL,DOUBLE EXTENDED) на экран будет выдан результат 1.08420217248550Е-0019, что соответствует типу EXTENDED.
Это связано с тем, что все операнды вещественного выражения 1+epsilon/2 в операторе WHILE перед вычислением автоматически преобразуются к типу EXTENDED. Для получения правильного резуль-
тата (для REALTYPE = REAL он будет 9.09494701772928Е- 0013) программу необходимо изменить следующим образом:
{$N+,E+}
type RealType= Real;
var epsilon, epsl:RealType; begin
epsilon := 1; repeat
epsilon := epsilon/2; epsl := 1 + epsilon
until epsl = 1; WriteLn(2*epsilon)
end.
Тип REAL оптимизирован для работы без сопроцессора. Если ПК оснащен сопроцессором, использование типа REAL приведет к дополнительным затратам времени на преобразование REAL к EXTENDED (не надо использовать REAL на ПК с сопроцессором, так как дополнительные затраты времени на преобразование типов могут привести к потере всех преимуществ сопроцессора). При раз- работке программ, критичных к времени счета, следует заменять его типами SINGLE или DOUBLE: по сравнению с типом REAL ско- рость вычислений на машинах с сопроцессором в этом случае увели- чивается в 2–3 раза. Если в ПК нет арифметического сопроцессора, скорость обработки данных всех вещественных типов приблизитель- но одинакова.
58
Особое положение в Turbo Pascal занимает тип СОМР, который понимается, как вещественное число без экспоненциальной и дроб- ной частей. Фактически, СОМР – это «большое» целое число со зна- ком, сохраняющее 19...20 значащих десятичных цифр (во внутрен- нем представлении СОМР занимает 8 смежных байт). В то же вре- мя в выражениях СОМР полностью совместим с любыми другими вещественными типами: над ним определены все вещественные опе- рации, он может использоваться как аргумент математических функ- ций и т.д. Наиболее подходящей областью применения типа СОМР являются бухгалтерские расчеты: денежные суммы выражаются в копейках или центах и действия над ними сводятся к операциям с достаточно длинными целыми числами.
В Pascal нет функций возведения в степень, тригонометрических функций (tg, ctg, arcsin, arccos), но они могут быть реа- лизованы сочетанием стандартных функций:
Xn = EXP(N*LN(X)); tg(X) = SIN(X)/COS(X); ctg(X) = COS(X)/SIN(X);
arcsin(X) = ARCTAN(X/SQRT(1-SQR(X))); arccos(X) = ARCTAN(SQRT(1-SQR(X))/X).
4.2. Структурированные типы данных
Структура (от лат. structura – строение, расположение, поря- док) – совокупность устойчивых связей объекта, обеспечивающих его целостность и тождественность самому себе, т.е. сохранение ос- новных свойств при различных внешних и внутренних изменениях.
Рассмотрим следующую задачу: ввести с клавиатуры 20 вещест- венных чисел и вычислить их сумму, при этом каждое из чисел со- хранить в памяти для последующей обработки. Мы будем вынужде- ны ввести 20 имен переменных, что, естественно, очень неудобно.
Pascal позволяет работать с более сложными по своей конструк- ции типами. Они называются типами данных пользователя и отно- сятся к структурированным типам (от слова структура). Отличаются они тем, что переменные структурированного типа состоят не из од- ного элемента (как все стандартные типы – целые, вещественные, символьные и логические), а из нескольких элементов.
К структурированным типам относятся массивы, записи, множе- ства и файлы.
59
4.2.1. Массивы
Массив – это совокупность однотипных элементов. Отличитель- ные особенности: каждый компонент массива может быть явно обо- значен и к нему имеется прямой доступ; число компонент массива определяется при его описании и в дальнейшем не меняется.
Для обозначения компонент массива используется имя перемен- ной-массива и так называемые индексы, которые обычно указывают желаемый элемент. Тип индекса может быть только порядковым (кроме longint). Чаще всего используется интервальный тип (тип-диапазон).
Описание типа массива задается следующим образом:
type
имя типа = array[ список индексов ] of тип
имя типа – правильный идентификатор; список индексов – список одного или нескольких индексных типов, разделенных запя- тыми; тип – любой тип данных.
Вводить и выводить массивы можно только поэлементно. Определить переменную как массив можно и непосредственно
при ее описании, без предварительного описания типа массива, на- пример:
var a,b,c: array[1..10] of integer;
Если массивы a и b описаны как:
var
a = array[1..5] of integer; b = array[1..5] of integer;
то переменные a и b считаются разных типов. Для обеспечения со- вместимости типов применяется описание переменных через предва- рительное описание типа.
Если типы массивов идентичны, то в программе один массив мо- жет быть присвоен другому. В этом случае значения всех перемен- ных одного массива будут присвоены соответствующим элементам второго массива.
Вместе с тем, над массивами не определены операции отношения. Сравнивать два массива можно только поэлементно.
Так как type, идущий за ключевым словом of в описании масси- ва, – любой тип Pascal, то он может быть и другим массивом. Например:
type
mas = array[1..5] of array[1..10] of integer;
60
