Любой реально существующий тип данных, каким бы сложным он ни казался на первый взгляд, представляет собой простые составляющие, которыми процессор может манипулировать. В Object Pascal эти простые типы данных разбиты на две группы: порядковые, представляющие данные разных объемов, которыми процессор может легко манипулировать, и действительные, представляющие приближенно математические действительные числа. Разделение типов на порядковые и действительные несколько условно. Точно так же простые данные можно было бы разделить на числа и не числа. Однако в языке Object Pascal порядковые и действительные данные трактуются по-разному, и такое разделение даже полезно.
Порядковые типы
Из простых типов данных порядковые - самые
простые. В этих типах информация представляется
в виде отдельных элементов. Связь между
отдельными элементами и их представлением в
памяти определяет естественные отношения
порядка между этими элементами. Отсюда и
название порядковые.
В Object Pascal определены три группы порядковых типов
и два типа, определяемых пользователем. Группы -
это целые, символьные и булевы типы. Порядковые
типы, задаваемые пользователем, - это
перечисления и поддиапазоны.
Все значения любого порядкового типа образуют
упорядоченную последовательность, и значение
переменной порядкового типа определяется его
местом в этой последовательности. За исключением
переменных целых типов, значения которых могут
быть как положительными, так и отрицательными,
первый элемент любого порядкового типа имеет
номер 0, второй элемент - номер 1 и т.д. Порядковый
номер целого значения равен самому значению.
Отношение порядка определяет общие для данных
всех порядковых типов операции. Некоторые
стандартные функции такого вида встроены в Object
Pascal. Они представлены в табл. 1.1.
Для всех порядковых типов в Object Pascal существует
операция задания типа для преобразования целых
значений в значения соответствующих порядковых
типов. Если Т - имя порядкового типа, а Х - целое
выражение, то Т (X) воз-вращает значение Т с
порядковым номером X.
Операция | Описание |
Low (T) | Минимальное значение порядкового типа Т |
High(T) | Максимальное значение порядкового типа Т |
Ord(X) | Порядковый номер значения выражения порядкового типа. Для целого выражения - просто его значение. Для остальных порядковых типов Ord возвращает физическое представление результата выражения, трактуемое как целое число. Возп0ащаемое значение всегда принадлежит одному из целых типов |
Pred(X) | Предыдущее по порядку значение. Для целых выражений эквивалентно Х-1 |
Succ(X) | Следующее по порядку значение. Для целых выражений эквивалентно Х+1 |
Dec(V) | Уменьшает значение переменной на 1. Эквивалентно V :=Pred(V) |
Inc(V) | Увеличивает значение переменной на 1. Эквивалентно V :=Succ(V) |
Целые типы
В переменных целых типов информация
представляется в виде целых чисел, т.е. чисел не
имеющих дробной части. Определенные в Object Pascal
целые типы подразделяются на физические
(фундаментальные) и логические (общие). При
программировании удобнее использовать
логические целые типы, которые задают объем
переменных в зависимости от типа
микропроцессора и операционной среды таким
образом, чтобы достигалась максимальная
эффективность. Физические целые типы следует
применять лишь в тех случаях, когда в первую
очередь важны именно диапазон значений и
физический объем переменной. В Object Pascal
определены следующие целые типы.
Integer
Shortint
Smallint
Longint
Byte
Word
Cardinal
Обратите внимание, что один из этих целых типов
назван именно целым (integer). Это может иногда
приводить к путанице, но мы легко сможем ее
избежать, применяя термин целый к. группе типов, a
integer - к конкретному типу, определяемому в
программе этим ключевым словом. Переменные
физических целых типов имеют разные диапазоны
значений в зависимости от того, сколько байтов
памяти они занимают (что равно значению,
возвращаемому функцией SizeOf для данного типа).
Диапазоны значений для всех физических типов
перечислены в табл. 1.2.
Таблица 1.2. Физические целые типы
Тип | Диапазон значении | Физический формат |
Shortint | -128-127 | 8 бит, со знаком |
Smallint | -32 768-32 767 | 16 бит, со знаком |
Longint | -2 147 483 648-2 147 483 647 | 32 бит, со знаком |
Byte | 0-255 | 8 бит, без знака |
Word | 0-65 535 | 16 бит, без знака |
Диапазоны значений и форматы физических целых
типов не зависят от микропроцессора и
операционной системы, в которых выполняется
программа. Они не меняются (или, по крайней мере,
не должны меняться) с изменением реализации или
версии Object Pascal.
Диапазоны значений логических целых
типов (Integer и Cardinal) определяются совершенно иным
образом. Как видно из табл. 1.3, они никак не
связаны с диапазонами соответствующих
физических типов. Обратите внимание, что в Delphi по
умолчанию задано 32-разрядное представление.
Таблица 1.3. Логические целые типы
Тип | Диапазон значений | Физический формат |
Integer | -32 768-32 767 | 16 бит, со знаком (SmalIInt) |
Integer | -2 147 483 648-2 147 483 647 | 32 бит, со знаком (Longint) |
Cardinal | 0-65 535 | 16 бит, без знака (Word) |
Cardinal | 0-2 147483647 | 32 бит, без знака (Longint) |
Над целыми данными выполняются все операции,
определенные для порядковых типов, но с ними все
же удобнее работать как с числами, а не с
"нечисленными порядковыми типами". Как и
"живые" числа, данные целых типов можно
складывать (+), вычитать (-) и умножать (*). Однако
некоторые операции и функции, применяемые к
данным целых типов, имеют несколько иной смысл.
Операция | Результат |
Abs (X) | Возвращает абсолютное целое значение Х |
Х Div Y | Возвращает целую часть частного деления Х на Y |
Х Mod Y | Возвращает остаток частного деления Х на Y |
Odd (X) | Возвращает булево True (истина), если Х - нечетное целое, и False (ложь) - в противном случае |
Sqr (X) | Возвращает целый квадрат Х (т.е. Х*Х) |
Символьные типы
Смысл символьных данных очевиден, когда они
выводятся на экран или принтер. Тем не менее,
определение символьного типа может зависеть от
того, что подразумевать под словом символ. Обычно
символьные типы данных задают схему
взаимодействия между участками памяти разного
объема и некоторым стандартным методом
кодирования/декодирования для обмена символьной
информацией. В классическом языке Pascal не задано
никакой схемы, и в конкретных реализациях
применялось то, что на том же компьютере мог
использовать каждый.
В реализациях языка Pascal для первых
микропроцессоров была применена 7-битовая схема,
названная ASCII (American Standard tt for Information Interchange -
Американский стандартный код для обмена
информацией). Эта схема и поныне широко
распространена, но информация хранится, как
правило, в 8-битовых участках памяти.
Дополнительный бит удваивает число возможных
представлений символов, но реализации
расширенного набора символов ASCII часто бывают
далеки от стандарта. В данной версии Delphi
определен набор 8-битовых символов, известный как
расширенный (extended) ANSI (American National Standards Institute -
Американский национальный институт стандартов).
Как бы то ни было, символьную схему приходится
воспринимать так, как ее воспринимает
операционная система. Для оконных операционных
систем фирмы Microsoft это схема ANSI, включающая
ограниченное число предназначенных для вывода
международных знаков. В стремлении же применить
более обширный набор международных знаков весь
компьютерный мир переходит к 16-битовой схеме,
именуемой UNICODE, в которой первые 256 знаков
совпадают с символами, определенными в схеме ANSI.
Для совместимости со всеми этими
представлениями в Object Pascal определены два
физических символьных типа и один логический.
Физические типы перечислены ниже.
AnsiChar | Однобайтовые символы, упорядоченные в соответствии с расширенным набором символов ANSI |
WideChar | Символы объемом в слово, упорядоченные в соответствии с международным набором символов UNICODE. Первые 256 символов совпадают с символами ANSI |
Символьные типы объемом в двойное слово (32 бит)
отсутствуют.
Логический символьный тип именуется char. В
классическом языке Pascal char- единственный
символьный тип. В Delphi char всегда соответствует
физическому типу данных AnsiChar. У американских
программистов ассоциация символа с однобайтовой
ячейкой памяти укоренилась за долгие годы
настолько, что им зачастую просто не приходит в
голову, что можно использовать другие схемы
кодирования. Однако дискуссии по
интернационализации программ в Internet и World Wide Web
могут существенно изменить их отношение к
проблеме объема символьных данных. Применяя
логический тип char, следует делать реализации для
других микропроцессоров и операционных систем, в
которых char может определяться как WideChar. При
написании программ, которые могут обрабатывать
строки любого размера, для указания этого
размера рекомендуется применять функцию SizeOf, не
задавая ее жестко постоянной. Функция Ord (С), где С
- любая переменная символьного типа, возвращает
целое значение, которым символ С представлен в
памяти.
Chr (X) | Преобразует целую переменную в переменную типа char с тем же порядковым номером. В Delphi это эквивалентно заданию типа Char (X) |
UpCase | Преобразует строчную букву в прописную |
Булевы типы
На ранней стадии обучения программисты
осваивают понятие бита, два состояния которого
можно использовать для записи информации о
чем-либо, представляющем собой одно из двух. Бит
может обозначать 0 или 1, ДА или НЕТ, ВКЛЮЧЕНО или
ВЫКЛЮЧЕНО, ВЕРХ или НИЗ, СТОЯТЬ или ИДТИ. В Object Pascal
информация о чем-либо, что можно представить как
ИСТИНА (True) или ЛОЖЬ (False), хранится в переменных
булевых типов. Всего таких типов че-тыре, и они
представлены в табл. 1.4.
Таблица 1.4. Размеры переменных булевых типов
Тип | Размер |
Boolean | 1 байт |
ByteBool | 1 байт |
WordBool | 2 байт (объем Word) |
LongBool | 4 байт (объем Longint) |
По аналогии с целыми и символьными типами,
подразделяющимися на физические и логические,
естественно предположить, что ByteBool, WordBool и LongBool -
физические типы, Boolean - логический. Но в данном
случае это не совсем так. Все четыре типа
различны. Для Object Pascal предпочтителен тип Boolean,
остальные определены для совместимости с
другими языками программирования и
операционными системами.
Переменным типа Boolean можно присваивать только
значения True (истина) и False (ложь). Переменные ByteBool,
WordBool и LongBool могут принимать и другие порядковые
значения, интерпретируемые обычно как False в
случае нуля и True - при любом ненулевом значении.
Перечислимые типы
Type enum type=(first value, value2, value3, last value);
Обычно данные перечислимых типов содержат
дискретные значения, представляемые не числами,
а именами. Тип Boolean- простейший перечислимый тип
в Object Pascal. Булевы переменные могут принимать два
значения, выражаемые именами True и False, а сам тип
определен в Object Pascal так, как будто он объявлен
следующим образом:
Type Boolean=(False, True);
С помощью типа Boolean в Object Pascal выполняются
сравнения, большинство же перечислимых типов -
это просто списки уникальных имен или
идентификаторов, зарезервированных с конкретной
целью. Например, можно создать тип MyColor (мой цвет)
со значениями myRed, myGreen и myBlue (мой красный, мой
зеленый, мой синий). Это делается совсем просто:
Type MyColor=(myRed, myGreen, myBlue);
В этой строке объявлены четыре новых
идентификатора: MyColor, myRed, myGreen и myBlue.
идентификатором MyColor обозначен порядковый тип,
следовательно, в синтаксисе Object Pascal можно
применять этот идентификатор везде, где
разрешены перечислимые типы. Остальные три
идентификатора- это значения типа MyColor. Подобно
символьным и булевым типам перечислимые не
являются числами, и использовать их наподобие
чисел не имеет смысла. Однако перечислимые типы
относятся к порядковым, так что значения любого
такого типа упорядочены. Идентификаторам в
списке присваиваются в качестве порядковых
номеров последовательные числа. Первому имени
присваивается порядковый номер 0, второму - 1 и
т.д.
Поддиапазонные типы
Переменные поддиапазонного типа содержат
информацию, соответствующую о5которому
pаданному диапазону значений исходного типа,
представляющего любой порядковый тип, кроме
поддиапазонного. Синтаксис определения
поддиапазонного типа имеет следующий вид:
Type subrange type=low value...high value;
Поддиапазонные переменные сохраняют все
особенности исходного типа. Единственное
отличие состоит в том, что переменной
поддиапазонного типа можно присваивать только
значения, входящие в заданный поддиапазон.
Контроль за соблюдением этого условия задается
командой проверки диапазона (range checking).
Необходимость явно определять поддиапазонный
тип возникает нечасто, но все программисты
неявно применяют эту конструкцию при
определении массивов. Именно в форме
поддиапазонной конструкции задается схема
нумерации элементов массива.
Действительные типы
В переменных действительных типов содержатся
числа, состоящие из целой и дробной частей. В Object
Pascal определено шесть действительных типов. Все
типы могут представлять число 0, однако они
различаются пороговым (минимальным
положительным) и максимальным значениями,
которые могут представлять, а также точностью
(количеством значащих цифр) и объемом.
Действительные типы описываются в табл. 1.5.
Таблица 1.5. Действительные типы.
Тип | Порог | Максимальное значение | Количество значащих цифр | Объем (байт) |
Real | 2.9E-39 | 1.7Е38 | 11-12 | 6 |
Single | 1.5E-45 | 3.4Е38 | 7-8 | 4 |
Double | 5.0E-324 | 1.7Е308 | 15-16 | 8 |
Extended | 3.4E-4932 | 1.IE4932 | 19-20 | 10 |
Comp | 1.0 | 9.2Е18 | 19-20 | 8 |
Currency | 0.0001 | 9.2Е14 | 19-20 | 8 |
Целые типы представляют целые числа, т.е. числа,
дробная часть которых равна нулю. Разница между
двумя неодинаковыми целыми числами не может быть
меньше единицы. Именно благодаря этому целые
числа применяются для обозначения дискретных
величин, независимо от того, имеют ли реальные
объекты какое-либо отношение к числам.
Действительные типы предназначены для
представления чисел, которые могут иметь дробную
часть, поэтому они полезны для представления
величин, которые могут быть довольно близкими,
почти непрерывными.
Заметьте, именно почти. Несмотря на название
действительные, переменные этих типов
отличаются от математических действительных
чисел. В Object Pascal действительный тип - это
подмножество математических действительных
чисел, которые можно представить в формате с
плавающей запятой и фиксированным числом цифр.
Для невнимательных программистов ситуация
усугубляется тем, что в стандартных форматах IEEE
(Institute of Electrical and Electronic Engi-neers - Институт
инженеров- электриков и электронщиков),
применяемых в программах Delphi и вообще в
большинстве программ для Windows, возможно точное
представление только чисел с фиксированным
числом бит в дробной части. Удивительно, но такое
простое число, как 0,1, записывается в расширенном
формате IEEE с некоторой погрешностью, пусть очень
небольшой. Из-за этого представление с плавающей
запятой оказывается несколько неудобным для
программ, в которых сохраняется и выводится
фиксированное число десятичных разрядов
численных значений. Это относится и к программам,
работающим с ''живыми" деньгами.
Для частичного решения этой проблемы в Object Pascal
определены два формата с фиксированной запятой.
Тип Comp (computational - вычислительный) содержит только
целые числа в диапазоне от -263+1 до 263-1,
что примерно соответствует диапазону от -9,2х1018
до 9,2х1018. При программировании операций с
американской валютой разработчикам обычно
приходится искать естественный способ записи
денежных сумм, в котором целая часть числа
определяет количество долларов, дробная -
центов. Если такие значения записывать в
переменные типа Comp, придется представлять их в
виде целого числа центов. В этом случае следует
умножать значение на 100 для обращения центов в
доллары, а затем делить на 100, чтобы снова
получить центы.
Этих забот можно избежать, если воспользоваться
типом Currency. В этом случае задачу выбора масштаба
возьмет на себя компилятор. Физически значения
Currency записываются в память того же объема, что и
Comp, как целые числа, однако компилятор не
забывает вовремя разделить значение на 10 000 (не на
100!) для его приведения в соответствие с денежным
знаком и умножить на 10 000 перед записью в память.
Это обеспечивает абсолютную точность в четыре
десятичных знака после запятой.
В Delphi есть модуль System, содержащий ряд процедур
обработки данных действительных типов. Наиболее
распространенные из них перечислены в табл. 1.6.
Много полезных процедур содержится также в
модулях SysUtils и Math.
Таблица 1.6. Функции действительных типов
Функция | Возвращаемое значение |
Abs (x) | Абсолютная величина х |
АгсТаn(х) | Арктангенс х |
Cos (х) | Косинус х (х выражается в радианах, а не в градусах) |
Ехр (х) | Экспоненциальная функция от х |
Frac(x) | Дробная часть х |
Int (х) | Целая часть х. Несмотря на название, возвращает действительное значение (с плавающей запятой), т.е. просто устанавливает нуль в дробной части |
Ln (х) | Натуральный логарифм от х |
Pi | Число Пи (3.1416...) |
Round (х) | Ближайшее к х целое значение. Возвращает значение целого типа. Условие "ближайшее к х" не работает, если верхнее и нижнее значения оказываются равноудаленными (например, ес-ли дробная часть точно равна 0,5). В этих случаях Delphi перекладывает решение на опера-ционную систему. Обычно процессоры Intel решают эту задачу в соответствии с рекоменда-цией IEEE округлять в сторону ближайшего четного целого числа. Иногда такой подход на-зывают "банкирским округлением" |
Sin(x) | Синус х |
Sqr(x) | Квадрат х, т.е. X*X |
Sqrt (х) | Квадратный корень от х |
Тrunc (х) | Целая часть х. В отличие от Int, возвращающей действительное значение, Trunc возвращает целое |