Назад Домой! Дальше Глава 9. СОВМЕСТИМОСТЬ И
ПРЕОБРАЗОВАНИЕ ТИПОВ ДАННЫХ



Когда в тех или иных операциях или операторах присутствуют данные, относящиеся к различным 
типам, возникает вопрос о соответствии типов. В связи с этим говорят об идентичности типов, 
совместимости типов и совместимости типов для присваивания. Когда возникают проблемы с 
соответствием типов данных, можно осуществить преобразование тех или иных типов. Эти 
вопросы и будут рассмотрены в данном разделе.

9.1. Идентичность типов
Идентичность типов требуется от формальных параметров процедур и функций и соответствующих 
им фактических параметров во время вызова.

Два типа Т1 и Т2 идентичны в следующих случаях:
 - Т1 и Т2 - один и тот же идентификатор типа (например, Integer, Real и т.д.);
 - один тип объявляется эквивалентным другому.

Пример.
type
  Tl = Boolean;
  Т2 = Т1;
  ТЗ = Boolean;

Все типы: Tl, T2, ТЗ и Boolean - идентичные типы.

type
  Ml = array[1..5] of Integer; 
  M2 = array[1..5] of Integer;

Типы Ml и М2 - не идентичные типы. Однако VI и V2 - переменные идентичных типов:

var
VI, V2: array[1..5] of Integer;

9.2. Совместимость типов
Совместимость типов требуется в выражениях (в том числе и в операциях отношения).
Два типа Т1 и Т2 совместимы в следующих случаях:
 - Т1 и Т2 - один и тот же тип или они идентичны;
 - Т1 и Т2 - вещественные типы;
 - Т1 и Т2 - целые типы;
 - один тип - вещественный, а другой - целый;
 - один тип представляет собой тип-диапазон другого;
 - оба типа являются типами-диапазонами какого-то одного типа;
 - оба типа являются типами-множествами с совместимыми базовыми типами;
 - один тип является строкой, а другой - строкой или символом;
 - один тип - Pointer, а другой - любой тип-указатель;
 - один тип PChar, а другой - массив символов, заканчивающийся символом
   с кодом 0 (только при наличии ключа компилятора ($Х+) - см. п. 17.7.1);
 - оба типа являются указателями, полученными с помощью адресной операции @, 
   примененной к величинам идентичных типов (только при наличии ключа компилятора 
   {$Т+} - см. п. 17.7.1);
 - оба типа - процедурные типы с идентичными типами результатов (для типа-функции),
   идентичным числом параметров и попарной идентичностью типов этих параметров.

9.3. Совместимость для присваивания
Эта совместимость необходима, когда значение какого-то выражения
присваивается переменной, типизированной константе, функции. Если значение объекта 
типа Т2 присваивается объекту типа Т1, то это возможно в следующих случаях:
 - Т1 и Т2 - идентичные типы и не являются файловыми типами или структурированными 
   типами, содержащими компоненты файлового типа на любом уровне структурирования;
 - Т1 и Т2 - совместимые порядковые типы и значение типа Т2 находится в
   границах возможных значений объекта типа Т1;
 - Т1 и Т2 - вещественные типы и значение типа Т2 находится в границах
   возможных значений объекта типа Т1;
 - Т1 - вещественный тип, а Т2 - целый тип;
 - Т1 и Т2 - строки;
 - Т1 - строка, а Т2 - символ;
 - Т1 и Т2 - совместимые типы-множества и все компоненты значения типа
   Т2 находятся в множестве Т1;
 - Т1 и Т2 - совместимые указатели;
 - Т1 - типа PChar, a T2 - строковая константа (только при наличии ключа
   компилятора {$Х+} - см. п. 17.7.1);
 - Т1 - типа PChar, a T2 - массив символов, заканчивающийся символом с
   кодом 0 (только при наличии ключа компилятора {$Х+} - см. п. 17.7.1);
 - Т1 и Т2 - совместимые процедурные типы;
 - Т1  - процедурный тип, а Т2 - процедура или функция с идентичным
   типом результата, числом параметров и попарной идентичностью типов
   этих параметров;
 - Т1 и Т2 - объектные типы (см. п. 14) и Т2 - потомок Т1;
 - Т1 и Т2 - указатели на объектные типы (см. п. 14) и Т2 - указатель на
   потомок типа, на который указывает Т1.

9.4. Преобразование типов
В ряде случаев требуется преобразовать переменную одного типа в переменную другого типа. 
В Turbo Pascal такое преобразование осуществляется сравнительно просто, если переменные 
обоих типов имеют один и тот же размер. Для этого следует указать идентификатор типа, а 
за ним в круглых скобках переменную исходного типа. Если новый тип - структурированный, 
можно в случае необходимости выбрать компоненту в соответствии с общими правилами.

Пример. 
type
ByteRec = record
  Lo, Hi: Byte 
end; 

WordRec = record
  Low, High: Word 
end; 

PtrRec = record
  Ofs, Seg: Word 
end;

BytePtr = ^Byte; 
var
  B: Byte; 
  W: Word; 
  L: Longint; 
  P: Pointer; 
begin
  W := $1234;	(присвоение переменной W значения)
  В := ByteRec(W).Lo;
  {преобразование переменной типа Word в запись из двух байтов и выделение младшего байта}
  ByteRec(W).Hi := 0;
  {преобразование переменной типа Word в запись из двух байтов и запись в старший байт 
  значения 0}
  L := $01234567;	{присвоение переменной L значения}
  W := WordRec(L).Low;
  {преобразование переменной типа Longint в запись из двух
  слов и выделение младшего слова} 
  В := ByteRec(WordRec(L).Low).Hi;
  {преобразование переменной типа Longint в запись из двух слов, выделение младшего слова, 
  преобразование его в запись из двух байтов и выделение старшего байта} 
  В := BytePtr(L)^;
  {преобразование переменной типа Longint в указатель и получение значения параметра, на 
  который он указывает} 
  Р :=Ptr ($40,$49);
  {Присвоение указателю Р значения с помощью стандартной функции Ptr} 
  W := PtrRec(P).Seg;
  {преобразование указателя в запись из двух слов и выделение второго слова (фактически 
  адреса сегмента)} 
  Inc(PtrRec(P).Ofs, 4);
  {преобразование указателя в запись из двух слов, выделение первого слова (фактически 
  смещения адреса) и увеличение его величины на 4 с помощью стандартной процедуры Inc} 
end.

Такое преобразование возможно не только, когда исходный и окончательный типы имеют 
одинаковый размер. Оно возможно также в случае преобразования друг в друга двух порядковых 
типов (см. п. 3.2), независимо от их размера, а также преобразования параметра без типа 
(см. п. 10.3.4).
Rambler's Top100
Hosted by uCoz