ЭЛЕКТРОННАЯ БИБЛИОТЕКА КОАПП |
Сборники Художественной, Технической, Справочной, Английской, Нормативной, Исторической, и др. литературы. |
Часть 5 Глава 3. Типы При описании переменной необходимо указать ее тип. Тип переменной описывает набор значений, которые она может принимать, и действия, которые могут быть над ней выполнены. Описание типа определяет идентификатор, который обозначает этот тип. ЪДДДДДДДДДДДДДї ХНё ЪДДДї ХНё описание типаДДДіидентификаторГДДДі=ГДДДітипГДДДі;ГДД АДДДДДДДДДДДДДЩ ФНѕ АДДДЩ ФНѕ ЪДДДДДДДДДДДї тип ДДДДДДДДДіпростой типГДДДДДДДДДДДДДДДДДДДД і АДДДДДДДДДДДЩ і ЪДДДДДДДДДДДДДДДї і ГДДДДітип "указатель"ГДДДДДДґ і АДДДДДДДДДДДДДДДЩ і і ЪДДДДДДДДДДДДДДДї і ГДДДДіструктурный типГДДДДДДґ і АДДДДДДДДДДДДДДДЩ і і ЪДДДДДДДДДДДДДї і ГДДДДістроковый типГДДДДДДДДґ і АДДДДДДДДДДДДДЩ і і ЪДДДДДДДДДДДДДДДДДДї і АДДДДіидентификатор типаГДДДЩ АДДДДДДДДДДДДДДДДДДЩ Указание идентификатора в левой части описания типа означает, что он определен как идентификатор типа для блока, в котором указано это описание типа. Область действия идентификатора типа не включает его самого, исключение составляют типы указатель. Имеется шесть следующих основных классов типов: - простой тип; - строковый тип; - структурный тип; - тип указатель; - процедурный тип; - объектный тип. Простые типы Простые типы определяют упорядоченные множества значений. ЪДДДДДДДДДДДДДДї простой тип ДДДДВДіпорядковый типГДДДДДДДДДДДД і АДДДДДДДДДДДДДДЩ і і і ЪДДДДДДДДДДДДДДДДї і АДівещественный типГДДДДЩ АДДДДДДДДДДДДДДДДЩ ЪДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДї вещественный тип ДДДДіидентификатор вещественного типаГДДД АДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДЩ Идентификатор вещественного типа относится к числу стандартных идентификаторов, которые могут быть вещественными (Real), с одинарной точностью (Single), с двойной точностью (Double), с повышенной точностью (Extended) и сложными (Comp). Примечание: В Главe 1 вы можете найти описание того, как обозначать константы целого и вещественного типов. Порядковые типы Порядковые типы представляют собой подмножество простых типов. Все простые типы, отличные от вещественных типов, являются порядковыми и выделяются по следующим четырем характеристикам. - Все возможные значения данного порядкового типа представляют собой упорядоченное множество, и каждое возможное значение связано с порядковым номером, который представляет собой целочисленное значение. За исключением значений целочисленного типа, п ервое значение любого порядкового типа имеет порядковый номер 0, следующее значение имеет порядковый номер 1 и так далее для каждого значения в этом порядковом типе. Порядковым номером значения целочисленного типа является само это значение. В любом поря дковом типе каждому значению, кроме первого, предшествует другое значение, и после каждого значения, кроме последнего, следует другое значение в соответствии с упорядоченностью типа. - К любому значению порядкового типа можно применить стандартную функцию Ord, возвращающую порядковый номер этого значения. - К любому значению порядкового типа можно применить стандартную функцию Pred, возвращающую предшествющее этому значению значение. Если эта функция применяется к первому значению в этом порядковом типе, то выдается сообщение об ошибке. - К любому значению порядкового типа можно применить стандартную функцию Succ, возвращающую следующее за этим значением значение. Если эта функция применяется к последнему значению в этом порядковом типе, то выдается сообщение об ошибке. Синтаксис порядкового типа имеет следующий вид: ЪДДДДДДДДДДДДДДДДї порядковый тип ДВДДі отрезок типа ГДДДДДДДДДДДДДДДДДДД і АДДДДДДДДДДДДДДДДЩ і ЪДДДДДДДДДДДДДДДДї і ГДДіперечислимый типГДДДДДДДДДДДДДДДДґ і АДДДДДДДДДДДДДДДДЩ і і ЪДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДї і АДДіидентификатор порядкового типаГДДЩ АДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДЩ Турбо Паскаль имеет девять встроенных порядковых типов: integer (целое), shortint (короткое целое), longint (длинное целое), byte (длиной в байт), word (длиной в слово), boolean (булевское), wordbool (булевское размером в слово), longbool (длинное б улевское) и char (символьный). Кроме того, имеется два других класса определяемых пользователем порядковых типов: перечислимые типы и отрезки типов (поддиапазоны). Целочисленный тип В Турбо Паскале имеется пять предопределенных целочисленных типов: shortint (короткое целое), integer (целое), longint (длинное целое), byte (длиной в байт) и word (длиной в слово). Каждый тип обозначает определенное подмножество целых чисел, как эт о показано в следующей таблице. Таблица 3.1 Предопределенные целочисленные типы ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД Тип Диапазон Формат ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД короткое целое -128 .. 127 8 бит со знаком (Shortint) целое -32768 .. 32767 16 бит со знаком (Integer) длинное целое -2147483648 .. 2147483647 32 бита со знаком (Longint) длиной в байт 0 .. 255 8 бит без знака (Byte) длиной в слово 0 .. 65535 16 бит без знака (Word) ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД Арифметические действия над операндами целочисленного типа предполагают 8-битовую, 16-битовую и 32-битовую точность в соответствии со следующими правилами: - Тип целой константы представляет собой встроенный целочисленный тип с наименьшим диапазоном, включающим значение этой целой константы. - В случае бинарной операции (операции, использующей два операнда), оба операнда преобразуются к их общему типу перед тем, как над ними совершается действие. Общим типом является встроенный целочисленный тип с наименьшим диапазоном, включающим все в озможные значения обоих типов. Например, общим типом для целого и целого длиной в байт является целое, а общим типом для целого и целого длиной в слово является длинное целое. Действие выполняется в соответствии с точностью общего типа и типом результата является общий тип. - Выражение справа в операторе присваивания вычисляется независимо от размера или типа переменной слева. - Любые операнды размером в байт преобразуются к промежуточному операнду размером в слово, который совместим перед выполнением арифметической операции с типами Integer и Word. Значение одного целочисленного типа может быть явным образом преобразовано к другому целочисленному типу с помощью приведения типов. Примечание: Приведение типов описывается в Главах 4 и 6. Булевский тип Значения булевского типа обозначаются встроенными идентификаторами констант False и True. Поскольку булевский тип (Boolean) является перечислимым, между этими значениями имеют место следующие отношения: - False < True - Ord(False) = 0 - Ord(True) = 1 - Succ(False) = True - Pred(True) = False Символьный тип (char) Множеством значений этого типа являются символы, упорядоченные в соответствии с расширенным набором символов кода ASCII (Приложение В). При вызове функции Ord(Ch), где Ch - значение символьного типа, возвращается порядковый номер Ch. Строковая константа с длиной 1 может обозначать значение константы символьного типа. Любое значение символьного типа может быть получено с помощью стандартной функции Chr. Перечислимый тип Перечислимые типы определяют упорядоченные множества значений через перечисление идентификаторов, которые обозначают эти значения. Упорядочение множеств выполняется в соответствии с последовательностью, в которой перечисляются идентификаторы. ХНё ЪДДДДДДДДДДДДДДДДДДДДДДї ХНё перечислимый тип ДДі(ГДДісписок идентификаторовГДДі)ГД ФНѕ АДДДДДДДДДДДДДДДДДДДДДДЩ ФНѕ ЪДДДДДДДДДДДДДї список идентификаторов ДДДДДіидентификаторГДДДВДДДДДДДДД АДДДДДДДДДДДДДЩ і і ХНё і АДДДДДДДДДґ,іДДДДДДДДЩ ФНѕ При указании идентификатора в списке идентификаторов перечислимого типа он описывается как константа для блока, в котором указано описание перечислимого типа. Типом этой константы является описанный перечислимый тип. Порядковый номер перечислимой константы определяется ее позицией в списке идентификаторов при описании. Перечислимый тип, в котором описывается константа, становится ее типом. Первая перечислимая константа в списке имеет порядковый номер 0. Приведем пример перечислимого типа (масти карт): type suit = (club, diamond, heart, spade); Согласно этим описаниям diamond является константой типа suit. При применении функции Ord к значению перечислимого типа Ord возвращает целое число, которое показывает, какое положение занимает это значение в отношении других значений этого перечислимого типа. Согласно предшествующим описаниям, Ord(club) возвращ ает 0, Ord(diamond) возвращает 1 и так далее. Отрезки типа Отрезок типа прдставляет собой собой поддиапазон значений из порядкового типа, называемого главным типом. Определение отрезка типа включает наименьшее и наибольшее значение в поддиапазоне. Оно имеет следующий синтаксис: ЪДДДДДДДДДДДї ХННё ЪДДДДДДДДДДДї отрезок типаДДДДДі константа ГДДі..ГДДДі константа ГДД АДДДДДДДДДДДЩ ФННѕ АДДДДДДДДДДДЩ Обе константы должны иметь один и тот же порядковый тип. Отрезки типов, имеющие вид a..b, предполагают, что a меньше или равно b. Приведем примеры отрезков типов: 0..99 -128..127 club..heart Переменная отрезка типа имеет все свойства переменных главного типа, однако ее значение на этапе выполнения должно принадлежать указанному интервалу. Вещественный тип К вещественному типу относится подмножество вещественных чисел, которые могут быть представлены в формате с плавающей точкой с фиксированным числом цифр. Запись значения в формате с плавающей точкой обычно включает три значения - m, b и e - таким об разом, что m x b^e=n, где b всегда равно 2, а m и e являются целочисленными значениями в диапазоне вещественного типа. Эти значения m и e далее определяют диапазон представления и точность вещественного типа. Имеется пять видов вещественных типов: вещественное (Real), с одинарной точностью (Single), с двойной точностью (Double), с повышенной точностью (Extended) и сложное (Comp). Действия над типами с одинарной точностью, с двойной точностью и с повышенн ой точностью и над сложным типом могут выполняться только при наличии числового сопроцессора 8087 (который был описан ранее). Вещественные типы различаются диапазоном и точностью связанных с ними значений (см. Таблицу 3.2). Таблица 3.2 Диапазон представления и десятичные цифры для вещественных типов ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД Тип Диапазон Значащие цифры Размер в байтах ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД вещественное от 2.9x10^-39 до 1.7x10^38 от 11 до 12 6 (real) с одинарной точностью от 1.5x10^-45 до 3.4x10^38 от 7 до 8 4 (single) с двойной точностью от 5.0x10^-324 до 1.7x10^308 от 15 до 16 8 (double) с повышенной точностью от 1.9x10^-4951 до 1.1x10^4932 от 19 до 20 10 (extended) сложный от -2^63+1 до 2^63-1 от 19 до 20 8 (comp) ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД Примечание: Сложный тип содержит только целочисленные значения в диапазоне от -2^63+1 до 2^63-1, что приблизительно равно -9.2x10^18 и 9.2x10^18. Турбо Паскаль поддерживает две модели генерации кода для выполнения действий над вещественными типами: программную для чисел с плавающей точкой и аппаратную для чисел с плавающей точкой. Выбор соответствующей модели осуществляется с помощью директив ы компилятора $N. Программная поддержка чисел с плавающей точкой В состоянии {$N-}, которое устанавливается по умолчанию, генерируемый код выполняет все вычисления с вещественными типами программно, через вызов подпрограмм библиотеки исполняющей системы. Из-за соображений скорости и размера кода в этом состоянии допускаются только действия над переменными типа real (вещественное). Любая попытка оттранслировать операторы, выполняющие действия над типами с одинарной точностью, с двойной точностью, с повышенной точностью и над сложными типами, вызовет сообщение об ошибке. Аппаратная поддержка чисел с плавающей точкой (80x87) В состоянии {$N+} генерируемый код выполняет все вычисления над вещественными типами с помощью числового сопроцессора 80x87. Это состояние позволяет использовать все вещественные типы, однако оно требует наличия сопроцессора 80x87 на этапе компиляци и и выполнения. Строковые типы Значением строкового типа является последовательность символов с динамическим атрибутом длины (в зависимости от действительного числа символов при выполнении программы) и постоянным атрибутом размера в диапазоне от 1 до 255. Текущее значение атрибут а длины можно получить с помощью стандартной функции Length. ХННННННё строковый тип ДДіstringГДВДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД ФННННННѕ і і ХНё ЪДДДДДДДДДДДДДДДї ХНё і АДі[ГДіцелое без знакаГДДі]ГДДЩ ФНѕ АДДДДДДДДДДДДДДДЩ ФНѕ Отношение между любыми двумя строковыми значениями устанавливается согласно отношению порядка между значениями символов в соответствующих позициях. В двух строках разной длины каждый символ более длинной строки без соответствующего символа в более к ороткой строке принимает значение "больше"; например, 'Xs' больше, чем 'X'. Нулевые строки могут быть равны только другим нулевым строкам и являются наименьшими строковыми значениями. К символам в строке можно обращаться, как к компонентам массива. Примечание: См.раздел "Массивы, строки и индексы" в Главе 4. Структурные типы Структурный тип, характеризуемый методом структурирования и типами своих компонентов, имеет более одного значения. Если тип компонента является структурным, то получаемый в результате структурный тип имеет более одного уровня структурирования. Струк турный тип может иметь неограниченные уровни структурирования. ЪДДДДДДДДДДДДї структурный типДВДДДДДДДДДДДДДВДДі тип массив ГДДДДДДДДДДД і і АДДДДДДДДДДДДЩ і ХННННННё і і ЪДДДДДДДДДДДДДДДДДї і АДіpackedГДЩ ГДДімножественный типГДДДґ ФННННННѕ і АДДДДДДДДДДДДДДДДДЩ і і ЪДДДДДДДДДДДДї і ГДДіфайловый типГДДДДДДДДґ і АДДДДДДДДДДДДЩ і і ЪДДДДДДДДДДДДДї і ГДДіобъектный типГДДДДДДДґ і АДДДДДДДДДДДДДЩ і і ЪДДДДДДДДДДДДї і АДДі тип запись ГДДДДДДДДЩ АДДДДДДДДДДДДЩ Слово packed (упакованный) в описании структурного типа требует от компилятора уплотнить хранимые данные, даже за счет уменьшения скорости доступа к компоненту в переменной этого типа. Слово packed не имеет никакого действия в Турбо Паскале, посколь ку упаковка выполняется здесь автоматически всюду, где это возможно. Типы массив Массивы содержат фиксированное число компонентов одного типа, так называемого типа конпонента. На приводимой ниже синтаксической диаграмме тип компонента следует за словом of. ХННННННё ХНё ЪДДДДДДДДДДДДДї ХНё ХННё тип ДДіarray ГДі[ГДДДіиндексный типГДВДі]ГДДіofГДДї массив ФННННННѕ ФНѕ АДДДДДДДДДДДДДЩ і ФНѕ ФННѕ і і ХНё і і АДДДДДДДґ,ГДДДДДДДДЩ ЪДДДДДДДЩ ФНѕ і ЪДДБДДї і тип ГДДДД АДДДДДЩ ЪДДДДДДДДДДДДДДДДї индексный тип ДДДДДДі порядковый тип ГДДДДДДДДДДДДДДДДДДД АДДДДДДДДДДДДДДДДЩ В индексных типах, по одному для каждой размерности массива, указывается число элементов. Допустимыми индексными типами являются все порядковые типы, за исключением длинного целого и поддиапазонов длинного целого. Массив может быть проиндексирован п о каждой размерности всеми значениями соответствующего индексного типа. Число элементов поэтому равно числу значений в каждом индексном типе. Число размерностей не ограничено. Приведем пример типа массив: array[1..100] of real Если тип элемента в типе массив также является массивом, то результат можно рассматривать как массив массивов или как один многомерный массив. Например: array[boolean] of array[1..100] of array[Size] of real интерпретируется компилятором точно так же, как массив: array[boolean,1..10,Size] of real Кроме того, можно записать выражение: packed array[1..10] of packed array[1..8] of boolean как packed array[1..10,1..8] of boolean Для доступа к элементам массива необходимо указать идентификатор массива с одним или несколькими индексами в квадратных скобках Примечание: См. раздел "Массивы, Строки и индексы" в Главе 4. Тип массив, имеющий вид: packed array[m..n] of char где m меньше, чем n, называется упакованным строковым типом (слово packed можно опустить, поскольку оно не оказывает действия в Турбо Паскале). Упакованный строковый тип имеет некоторые свойства, не характерные для других типов массив. Примечание: См. "Тождественные и совместимые типы" далее в этой главе. Тип массива вида: array[0..X] of Char где X - положительное ненулевое целое, называется массивом с нулевой базой. Символьный массив с нулевой базой используется для хранения строк, завершающихся нулем. При разрешении расширенного синтаксиса (директива компилятора {$X+}) символьный массив с нулевой базой совместим со значением PChar. Полное обсуждение данного вопроса вы можете найти в Главе 13 "Модуль String". Типы запись Тип запись содержит установленное число элементов или полей, которые могут быть различных типов. Описание типа запись указывает тип каждого поля и идентификатор, который именует поле. ХННННННё ХННННННё тип запись ДДДДіrecordГДВДДДДДДДДДДДДДДДДДДДДДі end ГДДДД ФННННННѕ і ФННННННѕ і ЪДДДДДДДДДДДДї і АДісписок полейГДДЩ АДДДДДДДДДДДДЩ ЪДДДДДДДДДДДДДї списокДВДіфиксированнаяГДВДДДДДДДДДДДДДДДДДДДДДДДДДВДДДДДДДДД полей і ічасть і і і і АДДДДДДДДДДДДДЩ і ХНё ЪДДДДДДДДДДї і і ХНё і і АДі;ГДДДівариантнаяГДЩ АДі;ГДЩ і ФНѕ ічасть і ФНѕ і і АДДДДДДДДДДЩ АДДДДДДДДДДДДДДДДДДДДДДДДДЩ ЪДДДДДДДДДДДДДДДДДДДДДДї ХНё ЪДДДї фиксированнаяДДДДісписок идентификаторовГДДі:ГДДітипГДДВДДД часть АДДДДДДДДДДДДДДДДДДДДДДЩ ФНѕ АДДДЩ і і ХНё і АДДДДДДДДДДДДДДДґ;іДДДДДДДДДДДДДДДДДДДДДДДДЩ ФНѕ Фиксированная часть типа запись содержит список фиксированных полей вместе с идентификатором и типом для каждого поля. Каждое поле содержит информацию, которая всегда отыскивается одним и тем же способом. Приведем пример типа запись: record year: integer; month: 1..12; day: 1..31; end В вариантной части, изображенной на синтаксической диаграмме описания типа запись, память распределяется более чем для одного списка полей, поэтому доступ к информации может быть осуществлен более чем одним способом. Каждый список полей является вар иантом. Варианты налагаются друг на друга в памяти, поэтому в любое время возможен доступ ко всем полям во всех вариантах. вариант- ная ХННННё ЪДДДДДДДДї ХННё ЪДДДДДДДї часть-іcaseГВДДДДДДДДДДДДДДДДДДДітип поляі-іofГДДівариантГДВ ФННННѕі іпризнакаі ФННѕ АДДДДДДДЩ і і ЪДДДДДДДДї ХНё і АДДДДДДДДЩ і ХНё і АДіиденти- ГДі:ГДЩ АДДДДі;ГДДДДЩ іфикатор і ФНѕ ФНѕ АДДДДДДДДЩ ЪДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДї тип поля признакаДДДДіидентификатор порядкового типаГДДДДДДДДДД АДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДЩ ЪДДДДДДДДДї ХНё ХНё ХНё вариантДДДДіконстантаГДВДі:ГДДі(ГДВДДДДДДДДДДДДДДДДДДДі)ГДДД АДДДДДДДДДЩ і ФНѕ ФНѕ і ФНѕ і ХНё і і ЪДДДДДДДДДДДДї і АДДДДДДі,ГДДДДДДЩ АДісписок полейГДЩ ФНѕ АДДДДДДДДДДДДЩ Вы можете видеть на схеме, что каждый вариант идентифицирован по крайней мере одной константой. Все константы должны быть отличными друг от друга и иметь порядковый тип, совместимый с типом поля признака. Доступ к вариантным и фиксированным полям од ин и тот же. В вариантной части можно указать необязательный идентификатор - идентификатор признака (тега) поля. При наличии идентификатора признака поля он становится идентификатором дополнительного фиксированного поля записи - поля признака. Программа может ис пользовать значение поля признака для указания, какой вариант является активным в настоящий момент. Без указания поля признака программа выбирает вариант по другому критерию. Ниже приводятся несколько примеров типов запись: type Person = record firstName,lastName : string[40]; birthDate : Date; case citizen : boolean of True : (birthPlace: string[40]); False : (country : string[20]; entryPort : string[20]; entryDate : Date; exitDate : Date); end; Polygon = record x,y : real; case kind : Figure of rectangle : (height,wigth: real); triangle : (side1,side2,angle: real); circle : (radius: real); end Объектные типы Объектный тип является структурой, состоящей из фиксированного числа компонентов. Каждый компонент является либо полем, содержащим данные строго определенного типа, либо методом, выполняющим операции над объектом. По аналогии с описанием переменных, описание поля указывает тип данных этого поля и идентификатор, именующий поле: по аналогии с описанием процедуры или функции, описание метода указывает заголовок процедуры, функции, конструктора или деструктора. Объектный тип может наследовать компоненты другого объектного типа. Если T2 наследует от T1, то T2 является потомком T1, а T1 является родителем T2. Наследование является транзитивным, то есть если T3 наследует от T2, а T2 наследует от T1, то T3 наследует от T1. Область (домен) объектного типа состоит из него самого и из всех его наследников. ХННННННё Объектный тип ДіobjectГДДДДВДДДДДДДДДДДДДДДДВДДДДДДДДДДДДДДВДї ФННННННѕ і і і і і і і і і і ЪДДДДДДДДДДД і і ЪДДДДДДДДДДї і і Аі наследо- ГДЩ Аі список ГДЩ і і вание і і полей і і АДДДДДДДДДДЩ АДДДДДДДДДДЩ і ЪДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДЩ і ХННННННё АДВДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ end ГДДДД і ФННННННѕ і ХНё ЪДДДДДДДДДДДДДДДДДї і АДДі;ГДДДДДДі список методов ГДДЩ ФНѕ АДДДДДДДДДДДДДДДДДЩ ХНё ЪДДДДДДДДДДДДДДДДДДДДДДДДДДДДї ХНё Наследование ДДі(ГДДДі идентификатор типа объекта ГДДі)ГДДДДД ФНѕ АДДДДДДДДДДДДДДДДДДДДДДДДДДДДЩ ФНѕ ЪДДДДДДДДДДДДДДДДДДДДДДДї ХНё ЪДДДДДї ХНё Список полей ДДДДДі список идентификатора ГДДДі:ГДДДДґ тип Гі;ГВД АДДДДДДДДДДДДДДДДДДДДДДДЩ ФНѕ АДДДДДЩ ФНѕі і і АДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДЩ ЪДДДДДДДДДДДДДДДДДДї ХНё Список методов ДДі заголовок метода ГДВДДДДДДДДДДДДДДДДДДДДДДДДДДВґ;ГДВД АДДДДДДДДДДДДДДДДДДЩ і іФНѕ і і і ХНё ХНННННННННё і і і Аі;ГДДДДі virtual ГВДДДДВЩ і і ФНѕ ФНННННННННѕі і і і ЪДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДЩ і і і і ЪДДДДДДДДДДДДДДДДДДДДДДДДДї і і і АДДі целочисленная константа іДДДДДЩ і і АДДДДДДДДДДДДДДДДДДДДДДДДДЩ і АДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДЩ ЪДДДДДДДДДДДДДДДДДДДДДї Заголовок метода ДДДДВДДДДДДДДДі залоговок процедуры ГДДДДДДДД і АДДДДДДДДДДДДДДДДДДДДДЩ і ЪДДДДДДДДДДДДДДДДДДДДДї і ГДДДДДДДДДі заголовок функции ГДДі і АДДДДДДДДДДДДДДДДДДДДДЩ і і ЪДДДДДДДДДДДДДДДДДДДДДДДДї і ГДДДДДДДі заголовок конструктора ГДі і АДДДДДДДДДДДДДДДДДДДДДДДДЩ і і ЪДДДДДДДДДДДДДДДДДДДДДДДДї і АДДі заголовок деструктора ГДДДДДДДЩ АДДДДДДДДДДДДДДДДДДДДДДДДЩ Следующий исходный код приводит пример описания объектного типа. Далее во всем этом разделе вы найдете ссылки на данное описание. type Point = object X, Y: integer; end; Rect = object A, B: Point; procedure Init(XA, YA, XB, YB: integer); procedure Copy(var R: Rect); procedure Move(DX, DY: integer); procedure Grow(DX, DY: integer); procedure Intersect(var R: Rect); procedure Union(var R: Rect); function Contains(P: Point): boolean; end; StringPtr = ^string; FieldPtr = ^Field; Field = object X, Y, Len: integer; Name: StringPtr; constructor Copy(var F: Field); constructor Init(FX, FY, FLen: integer; FName: string); destructor Done; virtual; procedure Display; virtual; procedure Edit; virtual; function GetStr: string; virtual; function PutStr(S: string): boolean; virtual; end; StrFieldPtr = ^StrField; StrField = object(Field) Value: StringPtr; constructor Init(FX, FY, FLen: integer; FName: string); destructor Done; virtual; function GetStr: string; virtual; function PutStr(S: string): boolean; virtual; function Get: string; procedure Put (S: string); end; NumFieldPtr = ^NumField; NumField = object(Field) Value, Min, Max: integer; constructor Init(FX, FY, FLen: integer; FName: string; FMin, FMax: longint); function GetStr: string; virtual; function PutStr(S: string): boolean; virtual; function Get: longint; function Put(N: longint); end; ZipFieldPtr = ^ZipField; ZipField = object(NumField) function GetStr: string; virtual; function PutStr(S: string): boolean; virtual; end; В отличие от других типов, объектные типы могут описываться только в разделе описаний типов, находящемся на самом внешнем уровне области действия программы или модуля. Таким образом, объектные типы не могут описываться в разделе описаний переменных или внутри блока процедуры, функции или метода. Компоненты и область действия Тип компоненты файлового типа не может иметь объектный тип или любой структурный тип, содержащий компоненты объектного типа. Область действия идентификатора компоненты простирается за пределы домена его объектного типа. Более того, область действия идентификатора компонента простирается сквозь блоки процедур, функций, конструкторов и деструкторов, которые реализуют методы объектного типа и его наследников. Исходя из этих соображений, написание идентификатора компоненты должно быть уникальным внутри объектного типа и внутри всех его наследников, а также внутри всех его методов. Область действия идентификатора компонента, описанного в части private описания типа, ограничивается модулем (программой), которая содержит описание объектного типа. Другими словами, частные (private) компоненты-идентификаторы действуют, как обычные общедоступные идентификаторы в рамках модуля, который содержит описание объектного типа, а вне модуля любые частные компоненты и идентификаторы неизвестны и недоступны. Поместив в один модуль связанные типы объектов, можно сделать так, что эти объекты с могут обращаться к частным компонентам друг друга, и эти частные компоненты будут неизвестны другим модулям. Методы Описание метода внутри объектного типа соответствует опережающему описанию метода (forward). Таким образом, где-нибудь после описания объектного типа, но внутри той же самой области действия, что и область действия объявления объектного типа, метод должен реализоваться путем определения его описания. Если требуется уникальный идентификатор метода, то используется уточненный идентификатор метода. Он состоит из идентификатора типа объекта, за которым следуют точка и идентификатор метода. Как и любому другому идентификатору, идентификатору уточненн ого метода, если требуется, могут предшествовать идентификатор пакета и точка. Внутри описания объектного типа в заголовке метода могут указываться параметры описываемого объектного типа, даже если описание еще не завершено. Это иллюстрируется методами Copy, Intersect и Union типа Rect предыдущего примера. Виртуальные методы По умолчанию, методы являются статическими, однако могут, за исключением конструкторов, быть виртуальными (посредством включения директивы virtual в описание метода). Компилятор разрешает ссылки на вызовы статических методов во время процесса компил яции, тогда как вызовы виртуальных методов разрешаются во время выполнения. Это иногда называют поздним связыванием. Если объектный тип объявляет или наследует какой-либо виртуальный метод, то переменные этого типа должны быть инициализированы посредством вызова конструктора перед вызовом любого виртуального метода. Таким образом, объектный тип, который описывает или наследует виртуальный метод, должен также описывать или наследовать по крайней мере один метод-конструктор. Объектный тип может переопределять любой из методов, которые он наследует от своих предков. Если описание метода в потомке указывает тот же идентификатор метода, что и описание метода в предке, то объявление в потомке подавляет объявление в предке. Область действия переопределяющего метода расширяется до сферы действия потомка, в котором этот метод был введен, и будет оставаться таковой, пока идентификатор метода не будет переопределен снова. Переопределение статического метода не зависит от изменения заголовка метода. В противоположность этому, переопределение виртуального метода должно сохранять порядок, типы и имена параметров, а также типы результатов функций, если таковые имеются. Б олее того, переопределение опять же должно включать директиву virtual. Динамические методы В Турбо Паскале для Windows вводится дополнительный класс методов позднего связывания, которые называются динамическими методами. Динамические методы отличаются от виртуальных методов только тем, как они вызываются на этапе выполнения. Во всех други х отношениях динамический метод можно рассматривать, как эквивалентный виртуальному методу. Описание динамического метода аналогично описанию виртуального метода, но описание динамического метода должно включать в себя индекс динамического метода, который указывается сразу за ключевым словом virtual. Индекс динамического метода должен зада ваться целочисленной константой в диапазоне 1..65535 и представлять собой уникальное значение среди индексов динамического метода или других динамических методов, содержащихся в объектном типе или его предках. Например: procedure FileOpen(var Msg: TMessage); virtual 100; Переопределение динамического метода должны точно соответствовать порядку, типу и именам параметров и типу результата функции. Переопределение должно также включать в себя директиву virtual, за которой следует тот же индекс динамического метода, что и заданный в объектном типе предка. Примечание: Более подробно о динамических методах и различиях в вызове виртуальных и динамических методах рассказывается в Главе 17 "Объекты". Создание экземпляров объектов Экземпляр объекта создается посредством описание переменной или константы с типом объектного типа или путем применения стандартной процедуры New к переменной типа указатель на объектный тип. Результирующий объект называется экземпляром объектного ти па. var F: Field; Z: ZipField; FP: FieldPtr; ZP: ZipFieldPtr; С учетом этих описаний переменных F является экземпляром Field, а Z - экземпляром ZipField. Аналогично, после применения New к FP и ZP, FP будет указывать на экземпляр Field, а ZP - на экземпляр ZipField. Если объектный тип содержит виртуальные методы, то экземпляры этого объектного типа должны инициализироваться посредством вызова конструктора перед вызовом любого виртуального метода. Ниже приведен пример: var S: StrField; begin S.Init (1, 1, 25, 'Первое имя'); S.Put ('Ah'yr'); S.Display; ... S.Done; end; Если метод S.Init не вызывался, то вызов S.Display приведет в неудачному завершению данного примера. Важное замечание: Присваивание экземпляра объектного типа не подразумевает инициализации экземпляра. Правило обязательной инициализации применимо также к экземплярам, которые являются компонентами структурных типов. Например: var Comment: array [1..5] of StrField; I: integer; begin for I := 1 to 5 do Comment [I].Init (1, I + 10, 40, 'первое_имя'); ... for I := 1 to 5 do Comment [I].Done; end; Для динамических экземпляров инициализация, как правило, связана с размещением, а очистка - с удалением, что достигается благодаря расширенному синтаксису стандартных процедур New и Dispose. Например: var SP: StrFieldPtr; begin New (SP, Init (1, 1, 25, 'первое_имя'); SP^.Put ('Ah'yr'); SP^.Display; ... Dispose (SP, Done); end; Указатель на объектный тип совместим по присваиванию с указателем на любой родительский тип, поэтому во время выполнения программы указатель на объектный тип может указывать на экземпляр этого типа или на экземпляр любого порожденного (производного) типа. Например, указатель типа ZipFieldPtr может присваиваться указателям типа ZipFieldPtr, NumFieldPtr и FieldPtr, а во время выполнения программы указатель типа FieldPtr может либо иметь значение nil, либо указывать на экземпляр Field, NumField или ZipF ield, или на любой экземпляр производного по отношению к Field типа. Эти правила совместимости указателей по присваиванию применимы также к параметрам-переменным объектного типа. Например, методу Field.Copy могут быть переданы экземпляры типов Field, StrField, NumField, ZipField или любые другие экземпляры производно го от Field типа. Метод активизируется посредством определителя (десигнатора) метода, который представляется в форме Экземпляр.Метод, где "Экземпляр" является одним из экземпляров объектного типа, а "Метод" является методом объектного типа. Для статических методов объявляемый (определяется во время компиляции) тип экземпляра определяет, какой метод должен быть активизирован. Например, определители F.Init и FP.Init всегда будут активизировать метод Field.Init, так как описанным типом дл я F и FP является Field. Для виртуальных методов выбором управляет действительный (определяемый во время выполнения) тип экземпляра. Например, десигнатор FP.Edit может активизировать Field.Edit, StrField.Edit или ZipField.Edit, в зависимости от действительного типа экземпля ра, на который указывает FP. В общем случае, не существует никакого способа определить, какой метод был активизирован десигнатором виртуального метода. Вы можете разработать программу (аналогичную программе ввода бланков редактора), которая активизирует FP.Edit, а затем, без мо дификации этой программы, применить ее к экземпляру нового, непредвиденного дочернего по отношению к Field типа. Если желательна такого рода возможность расширения, то вам следует применять объектный тип с открытым для расширения множеством производный т ипов, а не тип записи с ограниченным множеством вариантов. Множественные типы Диапазон значений множественного типа представляет собой мощность множества для определенного порядкового типа (базового типа). Каждое возможное значение множественного типа является подмножеством возможных значений базового типа. Переменная множественного типа может принимать как все значения множества, так и ни одного. ХННННННё ХННё ЪДДДДДДДДДДДДДДї множественный типДДі set ГДіofГДДіпорядковый типГДДД ФННННННѕ ФННѕ АДДДДДДДДДДДДДДЩ Базовый тип не должен иметь более 256 возможных значений, и порядковые значения верхней и нижней границы базового типа должны не превышать диапазона от 0 до 255. В силу этого базовый тип множества не может быть коротким целым (Shortint), целым (Inte ger), длинным целым (Longint) или словом (Word). Примечание: Операции над множественными типами описываются в разделе "Операции над множествами" в Главе 6. В разделе "Конструкторы множеств" показано как определять значения множества. Любой множественный тип может принимать значение [], которое называется пустым множеством. Файловые типы Файловый тип состоит из линейной последовательности компонентов, которые могут иметь любой тип за исключением файлового типа или структурного типа, содержащего компонент с файловым типом. Число компонентов не устанавливается описанием файлового типа . ХННННННё ХННё ЪДДДДДї файловый тип ДДДДДі file ГВДДіofГДДДі тип ГДДДДДДДДДДДДД ФННННННѕі ФННѕ АДДДДДЩ і і АДДДДДДДДДДДДДДДДДДДДЩ Если слово of и тип компонента опущены, то тип обозначает нетипизованный файл. Нетипизованные файлы представляют собой описатели ввода-вывода нижнего уровня, в основном используемые для прямого доступа к любому файлу на диске, независимо от его внут реннего формата. Стандартный файловый тип Text определяет файл, содержащий символы, упорядоченные в строки. Текстовые файлы используют специальные процедуры ввода-вывода, которые описываются в Главе "Ввод и вывод". Типы указатель Тип указатель определяет множество значений, которые указывают на динамические переменные определенного типа, называемого базовым типом. Переменная с типом указатель содержит адрес динамической переменной в памяти. ХННё ЪДДДДДДДДДДДї тип указатель ДДДДі ^ГДДДібазовый типГДДДДДДДДДДДДДДДДДД ФННѕ АДДДДДДДДДДДЩ ЪДДДДДДДДДДДДДДДДДДї базовый тип ДДДДДДДДіидентификатор типаГДДДДДДДДДДДДДДДДДД АДДДДДДДДДДДДДДДДДДЩ Если базовый тип является еще не описанным идентификатором, то он должен быть описан в той же самой части описания типов, что и тип указатель. Переменной-указателю можно присвоить значение с помощью процедуры New, операции @ или функции Ptr. Процедура New отводит новую область памяти в динамически распределяемой области для динамических переменных и сохраняет адрес этой области в переменно й-указателе. Операция @ ориентирует переменную-указатель на область памяти, содержащую существующую переменную, включая и те переменные, которые имеют идентификаторы. Функция Ptr устанавливает переменную-указатель на определенный адрес в памяти. Зарезервированное слово nil обозначает константу со значением указателя, которая ни на что не указывает (пустой указатель). Встроенный тип Pointer обозначает нетипизованный указатель, то есть указатель, который не указывает ни на какой определенный тип. Переменные типа Pointer могут быть разыменованы: указание символа ^ после такой переменной вызывает появление ошибки. К ак и значение, обозначаемое словом nil, значения типа Pointer совместимы со всеми другими типами указателей. Примечание: В разделе "Указатели и динамические переменные" в Главе 4 вы можете найти синтаксис ссылки на динамические переменые, которые указываются с помощью указателя-переменной. Встроенный тип PChar обозначает указатель на строку, завершающуюся нулем. PChar описывается следующим образом: type PChar = ^Char; Турбо Паскаль для Windows поддерживает набор правил расширенного синтаксиса, облегчающих работу со строками с завершающим нулем с помощью типа PChar. Полную информацию по данному вопросу можно найти в Главе 13 "Модуль Strings". Процедурные типы В стандартном Паскале процедуры и функции рассматриваются только как части программы, которые можно выполнять с помощью вызова процедуры или функции. В Турбо Паскале процедуры и функции трактуются гораздо шире: здесь допускается интерпретация процед ур и функций, как объектов, которые можно присваивать переменным и передавать в качестве параметров. Такие действия можно выполнять с помощью процедурных типов. Примечание: Полное описание процедурных типов можно найти в разделе "Процедурный типы". В описании процедурного типа задаются параметры, а для функции - результат функции. процедурный ХНННННННННё тип ДДВДДДДДДДіпроцедураГВДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД і ФНННННННННѕі і і ЪДДДДДДДДДДДДДДДДДДДДДДДДДДДДї і і і АДісписок формальных параметровГДДДЩ і і АДДДДДДДДДДДДДДДДДДДДДДДДДДДДЩ і і ХНННННННё ХНё ЪДДДДДДДДДї і АДіфункцияГДВДДДДДДДДДДДДДДДДДДДДДДДДі:ГДДірезультатГДДЩ ФНННННННѕ і ФНѕ АДДДДДДДДДЩ і і і ЪДДДДДДДДДДДДДДДДДї і АДісписок формальныхГДДЩ і параметров і АДДДДДДДДДДДДДДДДДЩ По существу синтаксис записи процедурного типа в точности совпадает с записью заголовка процедуры или функции, только опускается идентификатор после ключевого слова procedure или function. Приведем некоторые примеры описаний процедурного типа: type Proc = procedure; SwapProc = procedure(var X, Y: Integer); StrProc = procedure(S: String); MathFunc = function(X: Real): Real; DeviceFunc = function(var F: text): Integer; MaxFunc = function(A, B: Real; F: MathFunc): Real; Имена параметров в описании процедурного типа играют чисто декоративную роль - на смысл описание они не влияют. Турбо Паскаль не позволяет описывать функции, которые возвращают значения процедурного типа. Результат функции должен быть строкового, вещественного, целого, символьного, булевского типа, указателем или иметь перечислимый тип, определенный пользоват елем. Тождественные и совместимые типы Два типа могут быть тождественными, и эта тождественность (идентичность) является обязательной в некоторых констекстах. В других случаях два типа должны быть только совместимы или совместимы по присваиванию. Два типа являются тождественными, если он и описаны вместе, или если их определения используют один и тот же идентификатор типа. Тождественность типов Тождественность типов требуется только для переменных фактических и формальных параметров при вызове процедур и функций. Два типа, скажем T1 и T2, являются тождественными, если является истинным одно из следующих утверждений: T1 и T2 представляю собой один и тот же идентификатор типа; T1 описан как эквивалентный типу, тождественному T2. Второе условие означает, что T1 не обязательно должен быть описан как непосредственно эквивалентный T2. Следующие описания типов: T1 = integer; T2 = T1; T3 = integer; T4 = T2; означают, что T1, T2, T3, T4 и integer являются тождественными типами. Следующие описания типов: T5 = set of integer; T6 = set of integer; не определяют T5 и T6 как тождественные, поскольку set of integer не является идентификатором типа. Две переменные, описанные в одном и том же описании, например: V1, V2: set of integer; имеют тождественные типы, поскольку их описания не раздельны. Описания: V1: set of integer; V2: set of integer; V3: integer; V4: integer; означают, что V3 и V4 имеют тождественный тип, а V1 и V2 - нет. Совместимость типов Иногда, например, в выражениях и операциях сравнения, требуется совместимость типов. Совместимость типов, кроме того, является важной предпосылкой для совместимости по присваиванию. Совместимость типов имеет место, если выполняется по крайней мере одно из следующих условий: - Оба типа являются тождественными. - Оба типа являются вещественными типами. - Оба типа являются целочисленными. - Один тип является поддиапазоном другого. - Оба типа являются отрезками одного и того же основного типа. - Оба типа являются множественными типами с совместимыми базовыми типами. - Оба типа являются упакованными строковыми типами с одинаковым числом компонентов. - Один тип является строковым, а другой тип является или строковым типом, или упакованным строковым типом, или символьным типом. - Один тип является указателем (Pointer), а другой является любым типом указателей. - Один из типов представляет собой тип PChar, в другой - символьный массив с нулевой базой вида array[0..X] of Char (это применимо только при разрешении с помощью директивы {$X+} расширенного синтаксиса). - Оба типа являются процедурными с идентичными типами результатов, одинаковым числом параметров и соответствием между параметрами. Совместимость в операциях присваивания Совместимость по присваиванию необходима, если имеет место присваивание значения, например, в операторе присваивания или при передаче значений параметров. Значение типа T1 является совместимым по присваиванию с типом T2 (то есть допустим оператор T1:=T2), если выполняется одно из следующих условий: - T1 и T2 имеют тождественные типы, и ни один из них не является файловым типом или структурным типом, содержащим компонент с файловым типом на одном из своих уровней. - T1 и T2 являются совместимыми перечислимыми типами, и значения типа T2 попадают в диапазон возможных значений T1. - T1 и T2 являются вещественными типами, и значения типа T2 попадают в диапазон возможных значений T1. - T1 является вещественным типом, а T2 является целочисленным типом. - T1 и T2 являются строковыми типами. - T1 является строковым типом, а T2 является символьным типом. - T1 является строковым типом, а T2 является упакованным строковым типом. - T1 и T2 являются совместимыми упакованными строковыми типами. - T1 и T2 являются совместимыми множественными типами, и все члены значения типа T2 попадают в диапазон возможных значений T1. - T1 и T2 являются совместимыми типами указателей. - T1 представляет собой PChar, а T2 - строковую константу (это применимо только при разрешении с помощью директивы {$X+} расширенного синтаксиса). - T1 представляет собой тип PChar, а T2 - символьный массив с нулевой базой вида array[0..X] of Char (это применимо только при разрешении с помощью директивы {$X+} расширенного синтаксиса). - T1 и T2 являются совместимыми процедурными типами. - T1 представляет собой процедурный тип, а T2 - процедура или функция с идентичным типом результата, идентичным числом параметров и соответствием между типами параметров. - Объектны тип T2 совместим по присваиванию с объектным типом T1, если T2 является доменом T1. - Тип указателя Р2, указывающий на объект типа Т2, совместим по присваиванию с типом указателя P1, указывающим на объект T1, если T2 является доменом T1. На этапе компиляции и выполнения выдается сообщение об ошибке, если совместимость по присваиванию необходима, а ни одно из условий предыдущего списка не выполнено. Раздел описания типов Программы, процедуры и функции имеют для описания типов специальный раздел описания типов. Например: type Range = integer; Number = integer; Color = (red,green,blue); CharVal = Ord('A')..Ord('Z'); TextIndex = 1..100; TestValue = -99..99; TestList = array[TestIndex] of TestValue; TestListPtr = ^TestList; Date = record year: integer; month: 1..12; day: 1.. 31; procedure SetDate(D, M, Y : Integer); function ShowDate: String; end; MeasureData = record when: Date; count: TestIndex; data: TestListPtr; end; MeasureList = array[1..50] of MeasureData; Name = string[80]; Sex = (male,female); Person = ^PersonData; PersonData = record name,firstName: Name; age: integer; married: boolean; father,child,sibling: Person; case s: Sex of male: (bearded: boolean); female: (pregnant: boolean); end; PersonBuf = array(0..SizeOf(PersonData)-1] of byte; People = file of PersonData; IntFile = file of integer В этом примере Range, Number и integer являются тождественными типами. TestIndex является просто совместимым и совместимым по присваиванию, но не тождественным с типами Number, Range и integer. Обратите внимание на использование в описаниях CharVal и PersonBuf выражений-констант. |