Порядковые типы
К порядковым типам относятся (см. рис.4.1) целые, логический, символьный, перечисляемый и тип-диапазон. К любому из них применима функция ORD(X), которая возвращает порядковый номер значения выражения X. Для целых типов функция ORD(X) возвращает само значение X, т.е. ORD(X) = X для X, принадлежащего любому шелому типу. Применение ORD(X) к логическому, символьному и перечисляемому типам дает положительное целое число в диапазоне от 0 до 1 (логический тип), от 0 до 155 (символьный), от 0 до 65535 (перечисляемый). Тип-диапазон сохраняет все свойства базового порядкового типа, поэтому результат применения к нему функции ORD(X) зависит от свойств этого типа. К порядковым типам можно также применять функции: PRED (X) - возвращает предыдущее значение порядкового типа (значение, которое соответствует порядковому номеру ORD(X)- 1), т.е. ORD(PRED(X)) = ORD(X) - 1; SUCC (X) - возвращает следующее значение порядкового типа, которое соответствует порядковому номеру ORD(X) +1, т.е. ORD(SUCC(X)) = ORD(X) + 1. Например, если в программе определена переменная var с : Char; begin с := '5' ; end. то функция PRED(C) вернет значение '4', а функция SUCC(C) - значение '6'. Если представить себе любой порядковый тип как упорядоченное множество значий, возрастающих слева направо и занимающих на числовой оси некоторый отрезок, то функция PRED(X) не определена для левого, a SUCC(X) - для правого конца этого отрезка. Целые типы. Диапазон возможных значений целых типов зависит от их внутреннего представления, которое может занимать один, два или четыре байта. В табл. 4.1 приводится название целых типов, длина их внутреннего представления в байтах и диапазон возможных значений. Таблица 4.1 | Целые типы | Название | Длина, байт | Диапазон значений | Byte | 1 | 0. . .255 | ShortInt | 1 | -128. . .+127 | Word | 2 | 0. . .65535 | Integer | 2 | -32768.. .+32767 | LongInt | 4 | -2 147 483 648... +2 147 483 647 |
При использовании процедур и функций с целочисленными параметрами следует руководствоваться «вложенностью» типов, т.е. везде, где может использоваться WORD, допускается использование BYTE (но не наоборот), в LONGINT «входит» INTEGER, который, в свою очередь, включает в себя SHORTINT. Перечень процедур и функций, применимых к целочисленным типам, приведен в табл.4.2. Буквами b, s, w, i, l обозначены выражения соответственно типа BYTE, SHORTINT, WORD, INTEGER и LONGINT, x - выражение любого из этих типов; буквы vb, vs, vw, vi, vl, vx обозначают переменные соответствующих типов. В квадратных скобках указывается необязательный параметр. Таблица 4.2 Стандартные процедуры и функции, применимые к целым типам | Обращение | Тип результата | Действие | abs (x) | x | Возвращает модуль х | chr(b) | Char | Возвращает символ по его коду | dec (vx[, i] ) | - | Уменьшает значение vx на i, а при отсутствии i -на 1 | inc(vx[, i] ) | - | Увеличивает значение vx на i, а при отсутствии i - на 1 | Hi(i) | Byte | Возвращает старший байт аргумента | Hi(w) | To же | То же | Lo(i) | " | Возвращает младший байт аргумента | Lo (w) | " | То же | odd(l) | Boolean | Возвращает True, если аргумент - нечетное число | Random (w) | Как у параметра | Возвращает псевдослучайное число, равномерно распределенное в диапазоне 0...(w-l) | sgr (x) | X | Возвращает квадрат аргумента | swap ( i ) | Integer | Меняет местами байты в слове | swap (w) | Word | |
При действиях с целыми числами тип результата будет соответствовать типу операндов, а если операнды относятся к различным целым типам, - типу того операнда, который имеет максимальную мощность (максимальный диапазон значений). Возможное переполнение результата никак не контролируется, что может привести к недоразумениям, например: var а : Integer; х, у : Real; begin а := 32767; {Максимально возможное значение типа INTEGER} х := а + 2; {Переполнение при вычислении этого выражения!} у := LongInt(а)+2; {Переполнения нет после приведения переменной к более мощному типу} WriteLn(x:10:0, у:10:0) end. В результате прогона программы получим -32767 32769 Логический тип. Значениями логического типа может быть одна из предварительно объявленных констант FALSE (ложь) или TRUE (истина). Для них справедливы правила: ord(False) = 0; ord(True) = 1; False < True; succ(False)= True; pred(True) = False. Поскольку логический тип относится к порядковым типам, его можно использовать в операторе счетного типа, например: var 1 : Boolean; begin for 1 := False to True do .... Символьный тип. Значением символьного типа является множество всех символов ПК. Каждому символу приписывается целое число в диапазоне 0...255. Это число служит кодом внутреннего представления символа, его возвращает функция ORD. Для кодировки используется код ASCII (American Standard Code for Information Interchange - американский стандартный код для обмена информацией). Это 7-битный код, т.е. с его помощью можно закодировать лишь 128 символов в диапазоне от 0 до 127. В то же время в 8-битном байте, отведенном для хранения символа в Турбо Паскале, можно закодировать в два раза больше символов в диапазоне от 0 до 255. Первая половина символов ПК с кодами 0...127 соответствует стандарту ASCII (табл. 4.3). Вторая половина символов с кодами 128...255 не ограничена жесткими рамками стандарта и может меняться на ПК разных типов (в прил.2 приведены некоторые распространенные варианты кодировки этих символов). Таблица 4.3 Кодировка символов в соответствии со стандартом ASCII | Код | Символ | Код | Символ | Код | Символ | Код | Символ | 0 | NUL | 32 | BL | 64 | ® | 96 | ' | 1 | ЗОН | 33 | ! | 65 | A | 97 | a | 2 | STX | 34 | " | 66 | В | 98 | b | 3 | ЕТХ | 35 | # | 67 | С | 99 | с | 4 | EOT | 36 | $ | 68 | D | 100 | d | 5 | ENQ | 37 | % | 69 | E | 101 | e | 6 | АСК | 38 | & | 70 | F | 102 | f | 7 | BEL | 39 | ' | 71 | G | 103 | g | 8 | BS | 40 | ( | 72 | H | 104 | h | 9 | НТ | 41 | ) | 73 | I | 105 | i | 10 | LF | 42 | * | 74 | J | 106 | j | 11 | VT | 43 | + | 75 | k | 107 | k | 12 | FF | 44 | , | 76 | L | 108 | i | 13 | CR | 45 | - | 77 | M | 109 | m | 14 | SO | 46 | . | 78 | N | 110 | n | 15 | SI | 47 | / | 79 | О | 111 | 0 | 16 | DEL | 48 | 0 | 80 | p | 112 | P | 17 | DC1 | 49 | 1 | 81 | Q | 113 | q | 18 | DC2 | 50 | 2 | 82 | R | 114 | r | 19 | DC3 | 51 | 3 | 83 | S | 115 | s | 20 | DC4 | 52 | 4 | 84 | T | 116 | t | 21 | NAK | 53 | 5 | 85 | U | 117 | u | 22 | SYN | 54 | 6 | 86 | V | 118 | V | 23 | ETB | 55 | 7 | 87 | w | 119 | w | 24 | CAN | 56 | 8 | 88 | X | 120 | X | 25 | EM | 57 | 9 | 89 | У | 121 | У | 26 | SUB | 58 | : | 90 | z | 122 | z | 27 | ESC | 59 | / | 91 | [ | 123 | { | 28 | FS | 60 | < | 92 | \ | 124 | l | 29 | GS | 61 | = | 93 | ] | 125 | } | 30 | RS | 62 | > | 94 | ^ | 126 | ~ | 31 | US | 63 | ? | 95 | — | 127 | n |
Символы с кодами 0...31 относятся к служебным кодам. Если эти коды используются в символьном тексте программы, они считаются пробелами. При использовании их в операциях ввода-вывода они могут иметь следующее самостоятельное значение: Символ | Код | Значение | BEL | 7 | Звонок; вывод на экран этого символа сопровождается звуковым сигналом | НТ | 9 | Горизонтальная табуляция; при выводе на экран смещает курсор в позицию, кратную 8, плюс 1 (9, 17, 25 и т.д.) | LF | 10 | Перевод строки; при выводе его на экран все последующие символы будут выводиться, начиная с той же позиции, но на следующей строке | VT | 11 | Вертикальная табуляция; при выводе на экран заменяется специальным знаком | FF | 12 | Прогон страницы; при выводе на принтер формирует страницу, при выводе на экран заменяется специальным знаком | CR | 13 | Возврат каретки; вводится нажатием на клавишу Enter (при вводе с помощью READ или READLN означает команду «Ввод» и в буфер ввода не помещается; при выводе означает команду «Продолжить вывод с начала текущей строки») | SUB | 26 | Конец файла; вводится с клавиатуры нажатием Ctrl-Z; при выводе заменяется специальным знаком | SSC | 27 | Конец работы; вводится с клавиатуры нажатием на клавишу ESC; при выводе заменяется специальным знаком |
К типу CHAR применимы операции отношения, а также встроенные функции: СНR(В) - функция типа CHAR; преобразует выражение В типа BYTE в символ и возвращает его своим значением; UPCASE(CH) - функция типа CHAR; возвращает прописную букву, если СН -строчная латинская буква, в противном случае возвращает сам символ СН, например: var cl,c2: Char; begin cl := UpCase('s') ; c2 := UpCase ('Ф') ; WriteLn(cl,' ',c2) end. Так как функция UPCASE не обрабатывает кириллицу, в результате прогона этой программы на экран будет выдано S ф Перечисляемый тип. Перечисляемый тип задается перечислением тех значений, которые он может получать. Каждое значение именуется некоторым идентификатором и располагается в списке, обрамленном круглыми скобками, например: typе colors =(red, white, blue); Применение перечисляемых типов делает программы нагляднее. Если, например, в программе используются данные, связанные с месяцами года, то такой фрагмент программы: type ТипМесяц=(янв,фев,мар,апр,май,июн,июл,авг,сен,окт,ноя,дек); var месяц : ТипМесяц; begin ....... if месяц = авг then WriteLn('Хорошо бы поехать к морю!'); ....... end. был бы, согласитесь, очень наглядным. Увы! В Турбо Паскале нельзя использовать кириллицу в идентификаторах, поэтому мы вынуждены писать так: type TypeMonth=(jan,feb,mar,may,jun,jul,aug,sep,oct,nov,dec); var month: TypeMonth; begin ....... if month = aug then WriteLn('Хорошо бы поехать к морю!'); ....... end. Соответствие между значениями перечисляемого типа и порядковыми номерами этих значений устанавливается порядком перечисления: первое значение в списке получает порядковый номер 0, второе - 1 и т.д. Максимальная мощность перечисляемого типа составляет 65536 значений, поэтому фактически перечисляемый тип задает некоторое подмножество целого типа WORD и может рассматриваться как компактное объявление сразу группы целочисленных констант со значениями О, 1 и т.д. Использование перечисляемых типов повышает надежность программ благодаря возможности контроля тех значений, которые получают соответствующие переменные. Пусть, например, заданы такие перечисляемые типы: type colors = (black, red, white); ordenal= (one, two, three); days = (monday, tuesday, Wednesday); С точки зрения мощности и внутреннего представления все три типа эквивалентны: ord(black)=0, ..., ord(white)=2, ord(one)=0, ...ord(three)=2, ord(monday)=0, ...ord(Wednesday)=2. Однако, если определены переменные var col :colors; num :ordenal; day : days; то допустимы операторы col := black; num := succ(two); day := pred(tuesday); но недопустимы col := one; day := black; Как уже упоминалось, между значениями перечисляемого типа и множеством целых чисел существует однозначное соответствие, задаваемое функцией ORD(X). В Турбо Паскале допускается и обратное преобразование: любое выражение типа WORD можно преобразовать в значение перечисляемого типа, если только значение целочисленного выражения не превышает мощное1™ перечисляемого типа. Такое преобразование достигается применением автоматически объявляемой функции с именем перечисляемого типа (см. п. 4.4). Например, для рассмотренного выше объявления типов эквивалентны следующие присваивания: col := one; col := colors(0); Разумеется, присваивание col := 0; будет недопустимым. Переменные любого перечисляемого типа можно объявлять без предварительного описания этого типа, например: var col: (black, white, green); Тип-диапазон. Тип-диапазон есть подмножество своего базового типа, в качестве которого может выступать любой порядковый тип, кроме типа-диапазона. Тип-диапазон задается границами своих значений внутри базового типа: <мин.знач.>..<макс.знач.> Здесь <мин.знач. > - минимальное значение типа-диапазона; <макс.знач.> - максимальное его значение. Например: type digit = '0'..'9'; dig2= 48..57; Тип-диапазон необязательно описывать в разделе TYPE, а можно указывать непосредственно при объявлении переменной, например: var date : 1..31; month: 1. .12; Ichr : 'A'..'Z';. При определении типа-диапазона нужно руководствоваться следующими правилами: - два символа «..» рассматриваются как один символ, поэтому между ними недопустимы пробелы;
- левая граница диапазона не должна превышать его правую границу. Тип-диапазон наследует все свойства своего базового типа, но с ограничениями, связанными с его меньшей мощностью. В частности, если определена переменная
type days = (mo,tu,we,th,fr,sa,su); WeekEnd = sa .. su; var w : WeekEnd; begin ..... w := sa; ..... end; то ORD(W) вернет значение 5 , в то время как PRED(W) приведет к ошибке. В стандартную библиотеку Турбо Паскаля включены две функции, поддерживающие работу с типами-диапазонами: НIGН(Х) - возвращает максимальное значение типа-диапазона, к которому принадлежит переменная X; LOW(X) -возвращает минимальное значение типа-диапазона. Следующая короткая программа выведет на экран строку -32768...32767 var k: Integer; begin WriteLn(Low(k),'..',High(k)) end. |