* При перепечатке материалов ссылка на www.SeoLiga.ru обязательна!
Типы данных
15 апреля 2009
При описании переменной следует указать ее тип. Знание типа переменной необ- ходимо для определения набора значений, которые она может принимать, и действий, которые над ней можно выполнять. Для обозначения типа используют идентификато- ры. Ранее мы уже познакомились с такими типами, как натуральные и целые числа, обозначаемые идентификаторами Cardinal и Integer. Все типы можно разделить на шесть основных подразделов: • простой тип; • строковый тип; • структурный (структурированный) тип; • указательный тип; • процедурный тип; • вариантный тип. Простые типы Простые типы определяют упорядоченные множества значений. Это может быть или множество натуральных чисел (тип Cardinal), или множество целых чисел (тип integer), оптимизированных для работы с 32-разрядными приложениями, а также базовые целочисленные типы, перечисленные в табл. 3.2. Таблица 3.2. Целочисленные типы Тип Диапазон Формат Integer от -2147483648 до 2147483647 Знаковый 32 бита Cardinal от 0 до 4294967295 Беззнаковый 32 бита s h o r t i n t от-128 до 127 Знаковый 8 бит Smallint от-32768 до 32767 Знаковый 16 бит Longint от -2147483648 до 2147483647 Знаковый 32 бита Int64 от-26 3 до 263-1 Знаковый 64 бита Byte от 0 до 255 Беззнаковый 8 бит word от 0 до 65535 Беззнаковый 16 бит Longword от 0 до 4294967295 Беззнаковый 32 бита Целочисленные типы можно отнести и к порядковым типам. Порядковые типы представляют собой подмножество простых типов. Все простые типы, отличные от ве- щественных типов, являются порядковыми и имеют следующие четыре характеристики. 1. Все возможные значения данного порядкового типа представляют собой упоря- доченное множество, и каждое возможное значение связано с порядковым но- мером, который представляет собой целочисленное значение. За исключением значений целочисленного типа, первое значение любого порядкового типа име- ет порядковый номер 0, следующее значение имеет порядковый номер 1 и т.д. Порядковым номером значения целочисленного типа является само это значе- ние. В любом порядковом типе каждому значению, кроме первого, предшеству- ет другое значение, и после каждого значения, кроме последнего, следует дру- гое значение в соответствии с упорядоченностью типа.
2. К любому значению порядкового типа можно применить стандартную функ- цию Ord, возвращающую порядковый номер этого значения. 3. К любому значению порядкового типа можно применить стандартную функ- цию Pred, возвращающую порядковый номер предшествующего значения. Ес- ли эта функция применяется к первому значению в этом порядковом типе, то выдается сообщение об ошибке. 4. К любому значению порядкового типа можно применить стандартную функ- цию Succ, возвращающую порядковый номер последующего значения. Если эта функция применяется к последнему значению в этом порядковом типе, то выдается сообщение об ошибке. Например, если написать следующий оператор: Write(Pred(3));, то на экране отобразится число 2, а оператор Write (Succ (3)),- отобразит число 4. В небольшой программе, приведенной ниже, объявлена порядковая переменная х, которая может принимать значения от 1 до 5 (две точки, использованные при объявлении, говорят о том, что переменная может принимать любое значение толь- ко из этого диапазона). program Projectl; {$APPTYPE CONSOLE} var x: 1..5; { x может принимать значения 1,2,3,4,5. } begin x := 3; Writeln(x); Writeln(Pred(x)); Readln; end. В таком виде программа будет работать хорошо, и на экран будут выведены два числа: 3 и 2. Но если сделать присваивание х:=6, то компилятор зафиксирует ошибку. Булев тип Значения булева типа обозначаются встроенными идентификаторами констант False и True. Поскольку булев тип (Boolean) является перечислимым, то имеют ме- сто следующие отношения. False < True O r d ( F a l s e ) = О Ord(True) = 1 S u c c ( F a l s e ) = True Pred(True) = F a l s e Символьный тип Множеством значений этого типа являются символы, упорядоченные в соответст- вии с расширенным набором символов кода ASCII. При вызове функции Ord(Ch), где аргумент Ch — значение символьного типа, возвращается порядковый номер Ch. Строковая константа длиной 1 может обозначать константу символьного типа. Любое значение символьного типа может быть получено с помощью стандартной функции Chr. Например, функция вывода Write (Chr (110)),- отобразит на экран символ "п", а функция Write(0rd( 'п')) ,- отобразит значение 110. Перечислимый тип Перечислимые типы определяют упорядоченные множества значений через пере- числение идентификаторов, которые обозначают эти значения. Упорядочение мно- жеств выполняется в соответствии с последовательностью, в которой перечисляются идентификаторы. Все идентификаторы в списке перечислимого типа описываются как константы. Типом этой константы является описанный перечислимый тип. Порядковый номер перечислимой константы определяется ее позицией в списке идентификаторов. Первая перечислимая константа в списке имеет порядковый номер 0. Например, перечислимый тип для мастей карт должен быть описан так. type suit = (club, diamond, heart, spade); Согласно определению, diamond является константой типа s u i t с порядковым номером 1. Если применить функцию Ord к значению перечислимого типа, возвра- тится целое число, определяющее его по отношению к другим значениям этого типа. Например, Ord(club) возвращает 0, Ord(diamond) возвращает 1 и т.д. Вещественный тип К вещественному типу относится подмножество вещественных чисел, которые могут быть представлены в формате с плавающей запятой с фиксированным числом цифр, как показано в табл. 3.3. Таблица 3.3. Фундаментальные вещественные типы Тип Real48 Single Double Extended Comp Currency Диапазон OT2.9*10"39flo1.7*10M OTi.5*10""5flo3.4*1038 от5.0*10'324до1.7*10308 от 3.6*10'4951 до 1.Г104932 от -2"63+1 до 263-1 от -922337203685477.5808 до 922337203685477.5807 Значащие цифры 11-12 7-8 15-16 19-20 19-20 19-20 Размер в байтах 6 4 8 10 8 8 Типы Real48 в среде .NET уже не используется. Тип Сотр не рекомендуется ис- пользовать в среде .NET и он сохранен только для обратной совместимости с более ранними версиями языка Delphi. Тип Real называется групповым типом для вещественных типов и в .NET он эк- вивалентен типу Double. Групповые типы служат для удобства использования вещест- венных типов и в разных версиях они могут соответствовать различным типам. Директива компилятора {$REALCOMPATIBILITY ON} преобразует тип Real в шес- тибайтовый тип, но лучше этими возможностями не пользоваться, так как замедлится выполнение программы. Тип Extended (расширенный) используется для получения более точных вычисле- ний, но он плохо совмещается с различными платформами. Тип currency (коммерческий) используется для финансовых вычислений, так как разработан специально с целью исключения ошибок при проведении денежных рас- четов. Он преобразуется в тип Decimal для среды .NET. Ниже приведены примеры объявления переменных отдельных типов. var realType: Real; curencyType: Currency; Строковый тип Значением строкового типа является последовательность символов с динамически изменяемой длиной. Текущее значение атрибута длины можно получить с помощью стандартной функции Length, а с помощью процедуры SetLength можно установить длину строки. Основные строковые типы перечислены в табл. 3.4. Таблица 3.4. Строковые типы Тип Максимальная длина Требуемая память Использование s h o r t s t r i n g 255 символов от 2 Обратная совместимость до 256 байт A n s i S t r i n g 231 символов от 4 байт 8-разрядные символы ANSI, DBCS до 2 Гбайт ANSI, MBCS ANSI и т.д. Widestring 23 0 символов от 4 байт Символы Unicode; до 2 Гбайт многопользовательские серверы и многоязычные приложения Тип AnsiString часто называют длинной строкой, и он является предпочтитель- ным для большинства приложений. Групповой тип s t r i n g используется как обозна- чение типа для AnsiString. Например: var S: s t r i n g ; После такого объявления переменная s будет иметь тип AnsiString. При этом должна использоваться директива компилятора {$н+} (обычно она установлена по умолчанию). Если использовать директиву {$Н-}, то слово s t r i n g будет относиться к Shortstring. В .NET груповой тип string используется для обозначения типа System. String, который является классом и имеет методы для работы со строками. Отношение между любыми двумя строковыми значениями устанавливается со- гласно отношению порядка между значениями символов в соответствующих позици- ях. В двух строках разной длины каждый символ более длинной строки без соответст- вующего символа в более короткой строке принимает значение "больше"; например, 1 x s ' больше, чем ' х ' . Нулевые строки могут быть равны только другим нулевым строкам и являются наименьшими строковыми значениями. К символам в строке можно обращаться как к элементам массива. Ниже приведено консольное приложение с использованием строк. program Projectl; {$АРРТУРЕ CONSOLE} uses SysUtils; var SI: string; S2: string; begin 51 := 'Это строка'; 52 := SI; Writeln(S2); Write(Length(S2)); Readln; end. Здесь объявлены две строковые переменные si и S2. Первой переменной при- своено значение ' Это строка'. Затем значение первой переменной присваивается второй переменной и делается вывод значения второй переменной на экран. Также выводится значение длины второй строки, которое отобразит число 10. Если запустить это приложение на выполнение, то в некоторых случаях на экране вместо слов "Это строка" появятся абсолютно нечитаемые символы. Это связано с тем, что используемая DOS не русифицирована. Если создать графический интер- фейс пользователя и сделать вывод через него, то все будет в порядке. Для того чтобы сделать осмысленный вывод в консольном приложении, пользуйтесь английским ал- фавитом, или установите программу русификации DOS. При компиляции программ с среде Delphi 8, разработанных на основе библиотек VCL, необходимо учитывать несовпадение строковых типов. В табл. 3.5 приведено со- ответствие строковых типов VCL и CLR. Таблица 3.5. Соответствие строковых типов VCL и CLR Категория Тип Delphi Тип CLR Строки string System.String AnsiChar Borland.Delphi.System.AnsiChar ShortString Borland.Delphi.System.ShortString AnsiString Borland.Delphi.System.AnsiString WideString System.String Также необходимо учитывать структуру строк, используемых на платформе .NET. Строки в .NET являются постоянными, и при конкатенации происходит не класси- ческое объединение строк, а создание новой строки, что значительно замедляет ра- боту программы, где производятся многочисленные операции со строками. В таких случаях лучше использовать класс StringBuilder, который специально создан в .NET для работы со строками. Структурные типы Структурные типы характеризуются методами структурирования, типами своих компонентов и имеют больше одного значения. Структурные типы могут иметь неог- раниченное число уровней. Слово packed (упакованный) в описании структурного типа требует от компилятора уплотнить хранимые данные, даже за счет уменьшения скорости доступа к элементам в переменной этого типа. Тип array Тип array (массив) содержит фиксированное число элементов одного типа. Для доступа к элементам массива используются индексы. Массив может иметь неограни- ченное число размерностей, и для каждой размерности массива указывается число элементов. Допустимыми индексными типами являются все порядковые типы, диапа- зон которых не превышает 2 Гбайта. Массив может быть проиндексирован по каждой размерности всеми значениями соответствующего индексного типа, поэтому число элементов равно числу значений в каждом индексном типе. Объявление переменной МуАггау типа array может выглядеть так. var МуАггау: array[1..100] of Char; Можно создать тип двумерного массива следующим образом: type TMatrix = a r r a y [ 1 . . 1 0 ] of array[1..5O] of Real; Такое объявление эквивалентно следующему: type TMatrix = array[1..10, 1..50] of Real; В данном случае удобно считать, что тип элемента в типе array также является массивом. Трехмерный массив можно описать так: 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 И Л И ' • . • p a c k e d a r r a y [ 1 . . 1 0 , 1..8] of B o o l e a n Для доступа к элементам массива необходимо указать идентификатор массива с одним или несколькими индексами в квадратных скобках. Например, выражение Matrix[2,25] обеспечит доступ к 25-му элементу второй строки. То же самое мы по- лучим, если напишем Matrix[2] [25]. Тот тип массива, который был рассмотрен выше, называется статический массив. Размер массива (число элементов) задан при объявлении и менять его в процессе ра- боты программы нельзя. Но чаще всего необходимо иметь массив, размеры которого не известны до начала работы программы, причем они должны будут меняться в про- цессе работы. Это необходимо как для экономии памяти, так и для удобства работы, поэтому разработан тип динамический массив. Динамический массив в чем-то проще статического, так как его можно индексировать только целочисленными значениями, которые всегда начинаются с 0. Его объявление происходит следующим образом. var MyFlexibleArray: array of Real; Как видно, здесь не задаются размеры массива — они устанавливаются в процессе работы с помощью процедуры SetLength. SetLength(MyFlexibleArray, 20); Таким образом массив будет состоять из 20 элементов типа Real. При необходи- мости это значение можно изменить с помощью той же процедуры. Следует отметить, что статический массив работает быстрее, так как его значения размещаются в стеке, т.е. к ним обеспечивается быстрый доступ. Элементы динамиче- ского массива размещаются в куче, и доступ к ним происходит медленнее, но об этих моментах поговорим позже. Сейчас рассмотрим простую программу. program Projectl; {$APPTYPE CONSOLE} uses SysUtils; var arrStat: array [-1. . l-,--2 . . 2] of Integer; arrDyn: array of Byte; i, j: Integer; begin for i:=-l to 1 do for j:=-2 to 2 do a r r S t a t [ i ] [j] := i + j ; for i : = - l to 1 do for j : = - 2 to 2 do W r i t e l n ( a r r S t a t [ i , j ] ) ; Writeln; SetLength(arrDyn, 5); Writeln(Length(arrDyn)); for i:=0 to 4 do arrDyn[i] := i ; for i:=0 to 4 do Writeln(arrDyn[i]); Readln; end. Здесь объявлены два массива: статический с элементами типа Integer и динами- ческий с элементами типа Byte. Для статического массива заданы произвольные гра- ницы диапазонов. Сначала статический массив заполняется значениями (это циклы for), а затем эти значения выводятся на экран (тоже в цикле for). Затем то же самое происходит и с динамическим массивом. Длина динамического массива устанавлива- ется равной 5, т.е. в нем может разместиться не более 5 элементов с индексами от О до 4. Выражение Writeln (Length (arrDyn)) ; возвратит значение 5. В данном случае можно выделить еще одно преимущество языка Delphi — проверка границ диапазонов массивов. Например, в языке C++ такой проверки нет, и поиск оши- бок, связанных с выходом за границы диапазона, затруднителен. Такие ошибки могут проявляться достаточно спонтанно, и их трудно связать с нарушением границы диапа- зона. Например, может произойти зависание программы в самом неожиданном месте. Встроенную в Delphi проверку диапазонов можно включать и отключать, для чего необходимо выполнить команду меню Projects^Options... или нажать клавиши <Ctrl+Shft+Fll>. В открывшемся окне Project Options For выберите вкладку Compiler и в блоке Runtime errors установите флажок для переключателя Range checking. Теперь попробуйте ввести неправильное значение (например, сделать цикл не до 4, а до 5) и запустите программу. Появившееся диалоговое окно сообщит об ошибке. Во время проектирования проверку диапазона необходимо включать, но после от- ладки программы ее лучше выключить, при этом дополнительные коды проверки диапазона будут убраны и программа будет работать быстрее. Тип record Тип record (запись) содержит установленное число элементов или полей, которые могут быть различных типов. В описании записи указывается тип каждого поля и иден- тификатор, который именует поле. Ниже приведен пример объявления типа record. type TDate = record year: Integer; month: 1. .12; day: 1..31; end; Ключевое слово record определяет начало записи, в конце которой находится ключевое слово end. Между этими словами определены поля. В данном случае это поле year типа integer и поля с порядковыми переменными month и day, прини- мающие значения 1. . 12 и 1. . 31 соответственно. Этой записи присвоено имя TDate. Новый тип для даты можно объявить и так: type TDateRec = record Year: Integer; Month: (Jan, Feb, Mar, Apr, May, Jun, Jul, Aug, Sep, Oct, Nov, Dec) ; Day: 1..31; end; и использовать ее в своих программах, поскольку датами приходится пользоваться до- вольно часто. Единственное отличие от более раннего примера — здесь для поля Month использован перечислимый тип. Например, можно объявить переменную типа TDateRec: var Recordl: TDateRec; и присвоить ей значения следующим образом: with Recordl do begin Year := 1904; Month := Jun; Day := 16; end; Здесь использована конструкция с ключевым словом with, за которым идет иден- тификатор, используемый со всеми остальными идентификаторами. Без этой конст- рукции присваивание необходимо делать так: Recordl.Year := 1904; Recordl.Month := Jun; Recordl.Day := 16; Таким образом, сначала идет имя переменной, а за ней, через точку, имя поля. Это менее наглядно, и код получается весьма громоздким, особенно если в записи много полей. В записи можно применить конструкцию, которая позволяет в одном поле разме- щать различные типы. Такую конструкцию выделяют как вариантную часть. Рассмот- рим следующую программу. program Projectl; {$APPTYPE CONSOLE} type TRecl = record first: Integer; case Integer of 1: (second: Word); 2 : (three: Char) ; end; var TestRecord: TRecl; begin TestRecord.first := 5; TestRecord.second := 110; Writeln(testRecord.first); Writeln(testRecord.three); Readln; end. Здесь объявляется новый тип TRecl типа record, где для второго поля использу- ется конструкция с ключевым словом case, т.е. в одном поле может размещаться ли- бо переменная типа word, либо переменная типа char (это видно из программы). По- сле объявления переменной TestRecord типа TRecl ей были присвоены значения. Для второй переменной было введено значение 110, но оно было считано как символ, и на экране отобразилась буква "п", т.е. значение 110 было считано как буква "п". Это удобно использовать для преобразования типов, не прибегая к прямым методам приведения типов. Такой способ также используют, если необходимо сделать выбор из множества элементов. Например: type TShapeList = (Rectangle, Triangle, Circle, Ellipse, Other); TFigure = record case TShapeList of Rectangle: (Height, Width: Real); Triangle: (Sidel, Side2, Angle: Real); Circle: (Radius: Real); Ellipse, Other: (); end; Тип class Тип class (класс) является структурой, состоящей из фиксированного числа компонентов. Каждый компонент класса является либо полем, содержащим данные строго определенного типа, либо методом (процедурой или функцией). По аналогии с описанием переменных, в описании поля указывается тип данных этого поля и дентификатор, именующий поле: по аналогии с описанием процедуры или функ- ции, описание метода указывает заголовок процедуры, функции, конструктора или деструктора. Класс может наследовать компоненты другого класса. Если Т2 наследует Т1, то принято говорить, что Т2 является потомком или наследником Tl, a T1 является ро- дительским для Т2. Часто говорят, что Т2 является производным от Tl, a T1 является базовым для Т2. Можно еще сказать и так: Т1 — это суперкласс для Т2, если Т2 — непосредственный наследник Т1. Наследование называют транзитивным, например, если ТЗ наследует от Т2, а Т2 наследует от Tl, то ТЗ наследует и от Tl. Но об этом поговорим подробнее, когда бу- дем изучать методы объектно-ориентированного программирования. В данном случае, как и для приведенных выше типов, также можно говорить вме- сто "тип s e t " просто "множество". Этот математический термин вполне применим в энном случае, так как этот тип set представляет именно множество, и над ним можно производить все те же действия, что и над математическими множествами. Диапазон значений множества представляет собой мощность множества для опреде- ленного порядкового (базового) типа. Каждое возможное значение множества являет- ся подмножеством возможных значений базового типа. Но в Delphi количество значе- ний базового типа не должно превышать 256, и порядковые значения верхней и ниж- ней границы базового тила не должны превышать диапазона от 0 до 255. Поэтому базовый тип множества не может быть коротким целым (shortint), целым (Integer), длинным целым (Longint) или словом (Word). Переменная для множества может принимать все значения множества либо не принимать ни одного. Ниже приводятся примеры объявления множества и операции над множествами. Для обозначения множества используются ключевые слова s e t of, за которыми определяется тип элементов множества. Множество можно создать так: type TSomelnts = 1..250; TIntSet = set of TSomelnts; или так: type TIntSet = s e t of 1..250; А объявить переменную для множества и присвоить ей значения можно таким образом: var Setl, Set2: TIntSet; Setl := [1, 3, 5, 7, 9]; Set2 := [2, 4, 6, 8, 10] Можно использовать две точки (. .) для задания диапазона. var MySet: set of ' a ' . . ' z ' ; MySet := [ ' a ' , ' b ' , ' c ' ] ; Еще несколько примеров корректных множеств. set of Byte set of (Club, Diamond, Heart, Spade) set of Char; Для проверки наличия определенного элемента в составе множества используется ключевое слово in. if 'a' in MySet then ... { что-то сделать }; Тип file Как и для остальных структурных типов, вместо слов "тип f i l e " можно говорить просто "файл". Следовательно, о переменной F i l e l типа f i l e можно сказать: "Файл F i l e l " , что обычно значительно удобнее. Создать файл можно следующим образом: var Filel: file; Это самое общее определение файла, такие файлы называют нетипизованными. Можно конкретизировать тип файла, если добавить к слову f i l e ключевое слово of, за которым определить тип компонентов файла (это тип, который записывается или считывается при обращении к файлу). Компоненты файла могут иметь любой тип, за исключением типа f i l e (т.е. компонентами файла не могут быть сами файлы), или структурного типа, содержащего компонент с типом f i l e . В определении не устанав- ливается число компонентов. Например, имеем запись PhoneEntry, определяющую имя и номер телефона. type TPhoneEntry = record FirstName, LastName: string[20); PhoneNumber: string[15],• Listed: Boolean; end; Для записи этой информации в файл можно объявить (создать новый тип) файл TPhoneList (Номера телефонов) типа TPhoneEntry TPhoneList = f i l e of TPhoneEntry; или непосредственно описать файловую переменную типа TPhoneEntry. var Listl: file of TPhoneEntry; Но об этом поговорим подробнее, когда будем рассматривать вопросы ввода- вывода информации. Тип pointer По-русски такой тип можно назвать указательным типом, или указателем. Он оп- ределяет значения, которые не являются непосредственно используемыми величина- ми, а указывают на переменные определенного типа, размещенные в памяти. Таким образом, переменная указательного типа содержит адрес переменной в памяти. Если тип, на который указывает указатель, является еще не описанным идентифика- тором, то он должен быть описан в той же самой части описания типов, где и указатель. Указателю можно присвоить значение с помощью процедуры New, операции при- сваивания ссылки (@) или функции Ptr. Процедура New отводит новую область памя- ти в динамически распределяемой области (куче) для динамических переменных и со- храняет адрес этой области в указателе. Операция присваивания ссылки (@) ориенти- рует указатель на область памяти, содержащую существующую переменную, включая и те переменные, которые имеют идентификаторы. Функция P t r устанавливает указа- тель на определенный адрес в памяти. Ключевое слово n i l обозначает константу со значением указателя, которая ни на что не указывает (пустой указатель). Например, указатель на целочисленную переменную может быть объявлен сле- дующим образом. type PTypelnt = лInteger; Здесь символ " л " используется для того, чтобы переменную PTypelnt объявить как указатель на целочисленное значение. Дальше можно создать переменную указа- тельного типа, которой затем присвоить значение. var pointlnt: PTypelnt; Посмотрите, как это сделано в примере. type Pint = "Integer; var x: Integer; P o i n t e r l n t e g e r : Pint; begin х := 3; Pointerlnteger := @x; {указателю присваивается адрес х } Writeln(Pointerlnteger~); Readln; end. Переменная х типа integer получает значение 3. Указателю PointerLnteger присваивается значение адреса переменной х. Затем на экран выводится выражение PointerLnteger^, в данном случае это надо понимать как вывод значения, на кото- рое указывает указатель PointerLnteger. О том, что надо вывести значение не самого указателя, а то значение, на которое указывает указатель, говорит символ " Л " , размещенный после указателя. На экране будет отображено значение 3. Здесь пропущено начало программы, но, как вы уже имели возможность убедиться, оно одинаково для всех программ типа Console Application. В дальнейшем, если нет особой необходимости, листинги будут приводиться без начальной части. Когда объявляется новый тип, то принято идентификатор типа начинать с буквы "т". Например: TNewType. При объявлении указателя идентификатор принято начинать с бук- вы "р": PNewPointer. Хотя это и не обязательно, лучше придерживаться этого правила. Встроенный тип PChar обозначает указатель на строку, которая завершается ну- лем. Тип PChar описывается следующим образом. type PChar = AChar; Delphi для Windows поддерживает набор правил расширенного синтаксиса, облег- чающих работу со строками с завершающим нулем, с помощью типа PChar. В системных модулях System и SysUtils объявлены некоторые стандартные ука- затели (табл. 3.6), которые можно использовать в программах. Директива компилятора $т используется для контроля типа указателя, сгенери- рованного с помощью оператора "в". Эта директива может иметь два состояния {$Т+} ИЛИ Таблица 3.6. Стандартные указатели Тип указателя На какой тип указывает PAnsiString, Pstring AnsiString PByteArray TByteArray (объявлен В SysUtils). Используется при преобразованиях типов, динамически размещая память для массивов PCurrency, PDouble, Currency, Double, Extended, Single PExtended, PSingle P i n t e g e r Integer POleVariant OleVariant PShortString Shortstring. Применяется при использовании кода с устаревшим типом Pstring PTextBuf TTextBuf (объявлен в Sysueils). Встроенный буфер в записи TTextRec для файлов PVarRec TVarRec (объявлен в System) Pvariant Variant PWideString WideString PWordArray TWordArray (объявлен в SysUtils). Используется при преобразованиях типов, динамически размещая память для массивов с 2-х байтовыми значениями Если установлено состояние {$т-}, то результатом операции с оператором "@" бу- дет нетипизированный указатель, который может использоваться со всеми другими типами указателей. Если установлено состояние {$т+}, тип результата будет иметь значение Лт, где т совместимо только с типом переменной.