Песни о Паскале
Шрифт:
Совместимость и преобразование типов
Поздравляю! Теперь вам знакомы все простые типы данных – солдаты нашей армии. Сражаясь в едином строю, они будут передавать при необходимости данные друг другу. Такая передача данных должна подчиняться определенным правилам. Они просты, но заставляют программиста всякий раз задуматься: то ли я делаю? А это придает программам надежность.
Далее рассмотрим правила, по которым данные одного типа обращаются в другой: вещественное число — в символ, или
Целое и целое
Все целые типы совместимы между собой, а значит позволено взаимное присваивание их значений. Но не забывайте о возможном нарушении диапазонов. Вот общее правило: переменные более ёмких старших типов всегда примут данные из младших типов своего братства. Обратное не возбраняется, но может вызвать нарушение диапазонов, например:
Var B: Byte; I: Integer; W: Word; L: Longint;
...
{ Эти операторы не вызовут нарушения границ диапазонов }
I:= B; W:=B; L:= W; L:=I;
{ Эти операторы могут повлечь нарушения диапазонов }
B:=I; I:=W; W:=L;
Когда число N не помещается в переменной, то в неё попадает лишь младшая часть числа N (т.е. остаток от деления N mod 256 или N mod 65536).
Целое и символ
Взаимно превращать эти типы данных мы научились при шифровании символа; напомню об этом. Функция Ord возвращает числовой код любого порядкового типа, в том числе и символа. А функция Char делает обратный фокус, превращая число в символ, вот примеры:
Writeln ( Ord(’D’) ); { 68 }
Writeln ( Char(68) ); { D }
Как видите, число в символ преобразуется через имя типа Char. Это общий прием, волшебная палочка для обращений типов данных. Например, булевых.
Целое и булево
Превратить булево в целое можно все той же функцией Ord.
Writeln ( Ord(False) ); { 0 }
Writeln ( Ord(True) ); { 1 }
А для обратного превращения воспользоваться именем типа Boolean.
Writeln ( Boolean(0) ); { False }
Writeln ( Boolean(1) ); { True }
Целое и перечисление
Вернемся к перечислению месяцев, вымышленному нами в предыдущей главе, где переменная была объявлена так:
var m : (Jan,Feb,Mar,Apr,May,Jun,Jul,Aug,Sep,Oct,Nov,Dec);
Превратить значение такой переменной в число можно функцией Ord. А наоборот? Пока нам этого не удавалось. Но после объявления пользовательского типа данных задача решается очень просто.
Type TMonth = (Jan,Feb,Mar,Apr,May,Jun,Jul,Aug,Sep,Oct,Nov,Dec);
Var m : TMonth;
...
m:= 3; { это ошибка }
m:= TMonth(3); { это равнозначно m:= Apr (счет идет от нуля) }
Здесь объявлен пользовательский
Вещественное и вещественное
Подобно целому братству, вещественное братство дружно между собой. Переменной одного вещественного типа можно присвоить значение другого типа, при условии, что это значение поместится в новое «жилище», то есть, не приведет к нарушению диапазона.
Целое и вещественное
Вещественным переменным можно присваивать целые значения, не задумываясь о последствиях, – преобразование происходит автоматически. Но обратная операция не так проста, поскольку здесь надо решить судьбу дробной части вещественного числа, которая не попадет в целочисленную переменную. Есть две возможности: либо отбросить дробную часть, либо округлить вещественное число до ближайшего целого. Для этого Паскаль предлагает две функции, возвращающие целочисленные значения: Trunc – усечение, и Round – округление. Вот примеры их вызова.
Writeln ( Trunc(3.75) ); { 3 }
Writeln ( Round(3.75) ); { 4 }
Writeln ( Round(3.25) ); { 3 }
Напоследок рассмотрите рис. 76, где показана общая картина совместимости и преобразования простых типов данных.
Строгий контроль типов в Паскале задуман для пущей надежности программам. В старых языках программирования (Си, Фортран) такого контроля либо не было, либо он был очень слаб. Программист перебрасывал данные как ему вздумается, не слишком заботясь о последствиях. Подобные вольности порождали массу ошибок. Теперь же Паскаль предлагает программисту следующее: пожалуйста, переноси данные, куда угодно, но при этом укажи явным образом, что ты делаешь.
Размеры переменных и типов данных
Иногда требуется знать не только содержимое переменных, но и объём занимаемой ими памяти. Разумеется, вы можете узнать это из таблиц, приведенных в справке или руководстве по языку. Размеры сложных типов данных тоже поддаются расчету. И все же лучший способ определить размер переменной некоторого типа – вызов псевдофункции SizeOf. В качестве параметра она принимает либо имя переменной, либо имя типа, а возвращает целое число – объём занимаемой памяти в байтах. Вот примеры.
Type TMonth = (Jan,Feb,Mar,Apr,May,Jun,Jul,Aug,Sep,Oct,Nov,Dec);
Var m : TMonth;
...
Writeln ( SizeOf(m) ); { 1 }
Writeln ( SizeOf(TMonth) ); { 1 }
Writeln ( SizeOf(Integer) ); { 2 }
Writeln ( SizeOf(Extended) ); { 10 }
Рис.76 – Совместимость и преобразования типов