
- •Процедуры и функции
- •Процедуры
- •Пример Вызов процедуры InpInt для ввода k целых чисел в массив m.
- •Функции
- •Формальные и фактические параметры
- •Параметры-значения Параметры-значения передаются основной программой в подпрограмму через стек в виде их копий. Сам параметр программы подпрограммой измениться не может.
- •Параметры-переменные
- •Этот вариант лучше предыдущего, так как в стеке не создается копия исходного массива, что улучшает быстродействие и экономит память.
- •Локализация имен
- •Пример Структура вложенной программы.
- •Основное правило Паскаля
- •Допустимые вызовы процедуры
- •Совместимость и преобразование типов данных
- •Параметры-массивы и строки открытого типа
- •Процедурные типы
- •Проблема совместимости
- •Рекурсия
- •Побочный эффект
- •Рекурсивная функция
- •Стеки для локальных переменных и параметров
- •Реализация стеков параметров в Паскале
Допустимые вызовы процедуры
Программа или процедура, откуда производится вызов
|
Процедуры, которые могут быть вызваны |
ShowScope Proc1 Proc 2 |
Proc1, Proc2 Proc1 Proc 1, Proc 2 |
Вложенные процедуры
program Nested;
область
действия m,
n,
outer
область
действия x,
y,
p,
q
inner procedure inner; var p, t: real;
область
действия p,
t
end; {inner}
begin {outer} …………… end; {outer}
begin {Nested} …………… end. {Nested}
Допустимые обращения к идентификаторам
|
|
|
Тело программы или процедуры |
Идентификаторы, к которым возможны обращения |
|
Nested |
m, n (глобальные переменные) оuter (глобальная процедура) |
|
Outer |
m, n (глобальные переменные) x, y (параметры) p,q (локальные переменные) оuter (глобальная процедура) inner (локальная процедура) |
|
Inner |
m, n (глобальные переменные) x, y (параметры outer ) Q (переменная, объявленная в outer) p,t (локальные переменные) оuter (глобальная процедура) inner (процедура, объявленная в outer) |
Совместимость и преобразование типов данных
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 – тип результата выражения его правой части.
Присваивание возможно, если:
-
Т1 и Т2 – один тип;
-
Т1 и Т2 – совместимые порядковые типы и значение Т2 лежит в диапазоне возможных значений Т1;
-
Т1 и Т2 – вещественные типы и значение Т2 лежит в диапазоне возможных значений Т1;
-
Т1 – вещественный тип, Т2 – целый;
-
Т1 – строка, Т2 – строка или символ;
-
Т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 в качестве фактических параметров могут быть использованы любые переменные простого типа, массивы, записи и др.
Параметр без типа внутри подпрограммы перед его использованием надо привести (преобразовать) к конкретному определенному типу.
Пример Программа для вычисления максимального значения с использованием функции с бестиповым формальным параметром.
type
tarr = array[1..100] of integer;
var
massiv: tarr;
maxim, i, k: integer;
function max(var mas; n: byte): integer;
type
tarray=array[1..maxint] of integer;
var ma:integer;
i:byte;
begin
ma:=tarray(mas)[1];
for i:=2 to n do
if ma<tarray(mas)[i] then
ma:=tarray(mas)[i];
end;
begin
writeln(‘Введите число элементов массива ’);
read(k);
writeln(‘Введите элементы массива’);
for i:=1 to k do
read(massiv[i]);
maxim:=max(massiv,k);
writeln(maxim);
end.