Turbo Pascal – типизированный язык. Концепция типов предполагает, что применяемые в языке операции определены только над операндами совместимых типов.
Совместимость типов учитывается при согласовании формальных и фактических параметров подпрограмм и выполнении операций присваивания.
Несовместимость типов определяется на этапе компиляции. Если типы операндов выражения или формальных и фактических параметров подпрограмм неодинаковы, но совместимы, то производится преобразование типов для приведения их к одному и тому же допустимому типу.
Принадлежат ли переменные одному типу данных, зависит от того, как в языке трактуется эквивалентность. Она может быть структурная и именная.
При первой анализируется структура переменных: число их компонентов и их типы.
Пример
type
t1=array [1..10] of integer;
t2=array [1..10] of integer;
var
v1,v2: t1;
v3: t2;
При структурной эквивалентности Т1 и Т2 – один тип.
В языке Pascal применяется именная эквивалентность. Типы переменных совпадают тогда и только тогда, когда при их описании используется один и тот же идентификатор типа. Т1 и Т2 – 2 разных типа!
Типы Т1 и Т2 идентичны (одинаковы), если
- Т1 и Т2 – один и тот же тип;
- определены один через другой, т.е.
type Т1=Т2;
type Т2=Т1;
При вычислении выражений и при выполнении операции присваивания операнды должны быть совместимы.
Во время вычисления выражений два типа операндов совместимы, если:
1) оба они одного типа;
2) один – вещественный, другой – целый;
3) один является диапазоном типа второго операнда;
4) оба – диапазоны одного и того же базового типа;
5) оба – множества, составленные из элементов одного и того же базового типа данных;
6) оба – строки;
7) один тип – строка, другой – символ.
Пусть Т1 – тип переменной левой части присваивания, Т2 – тип результата выражения его правой части.
Присваивание возможно, если:
1) Т1 и Т2 – один тип;
2) Т1 и Т2 – совместимые порядковые типы и значение Т2 лежит в диапазоне возможных значений Т1;
3) Т1 и Т2 – вещественные типы и значение Т2 лежит в диапазоне возможных значений Т1;
4) Т1 – вещественный тип, Т2 – целый;
5) Т1 – строка, Т2 – строка или символ;
6) Т1 и Т2 – совместимые множества и все элементы Т2 принадлежат множеству возможных значений Т1;
Преобразование типов может быть явным и неявным.
При явном преобразовании типов используют вызовы специальных функций, аргументы которых принадлежат одному типу, результат – другому.
Пример
Ord, Odd, Trunc, Round, Chr.
Данные одного типа могут автоматически (неявно) преобразовываться в данные другого типа перед выполнением операций в выражениях и через выполнение операций присваивания. Неявное преобразование типов возможно в трех случаях:
а) в выражениях из вещественных и целочисленных данных целые автоматически преобразуются в вещественные, результат будет вещественного типа;
б) при выполнении операции присваивания переменной вещественного типа значения целого типа значение целого типа преобразуется в значение вещественного типа, после чего оно присваивается переменной левой части оператора присваивания;
в) одна и та же область памяти попеременно содержит данные то одного, то другого типа (совмещение в памяти данных разных типов). Например, при использовании записей с вариантными полями.
Явное преобразование может быть с помощью стандартных функций и с помощью операции приведения типа.
Форма операции
<имя типа>( <имя переменной> / <выражение>);
Операция приведения может находиться, как в левой части оператора присваивания, так и в правой.
Если она находится в левой части оператора присваивания, то в скобках может быть только имя переменной. Если в правой, то и выражение.
Пример Явное преобразование символов и чисел.
uses crt;
var
si:0..255;
a:byte;
c:char;
begin
clcscr;
char(si):=’a’; {Приведение типа в левой части: из чего char
преобразуется для si!!}
writeln(char(si)+’s’); {as}
writeln(si); {97}
si:=ord(‘C’); {Приведение типа в правой части: во что char
преобразуется !!}
writeln(si); {67}
si:=byte (‘E’); {Приведение типа в правой части: во что char
преобразуется !!}
writeln(si); {69}
a:=byte(‘E’);
writeln(a); {69}
char(a):=’B’;
writeln(char(a)); {B}
writeln(a); {66}
byte(c):=si; {Приведение типа в левой части: из чего si
преобразуется для char!!}
writeln(byte(c)+200); {269}
writeln(c); {E}
byte(c):=a;
writeln(c); {B}
end.
Пример Явное преобразование целых и перечислимых типов.
type
Days=(mon, tues, wen, thurs, fri, sat, sun);
var
aDay:Days;
num:byte;
begin
clrscr;
Days(Num):=sun; {Приведение типа в левой части: из чего Days
преобразуется для byte !!}
writeln(ord(Days(num)),ord(sun),num); {666}
aDay:=Days(num); {Приведение типа в правой части: во что byte
преобразуется !!}
writeln(ord(Days(num)),ord(aDay),num); {666}
num:=byte(fri);
writeln(ord(fri), num); {44}
num:=ord(fri);
writeln(Ord(fri), num); {44}
aday:=Days(num+1);
writeln(ord(Days(num+1)), num+1); {55}
num:=byte(pred(fri));
writeln(num); {3}
end.
Бестиповые параметры
Можно использовать параметры-переменные и параметры-константы без указания типов.
Фактическим параметром может быть переменная любого типа; ответственность за правильность использования параметра возлагается на программиста.
Пример
function Equal(var Param1; Param2; Len:word);
Для формальных параметров Param 1, Param 2 в качестве фактических параметров могут быть использованы любые переменные простого типа, массивы, записи и др.
Параметр без типа внутри подпрограммы перед его использованием надо привести (преобразовать) к конкретному определенному типу.
Пример Программа для вычисления максимального значения с использованием функции с бестиповым формальным параметром.