- •Процедуры и функции
- •Процедуры
- •Пример Вызов процедуры InpInt для ввода k целых чисел в массив m.
- •Функции
- •Формальные и фактические параметры
- •Параметры-значения Параметры-значения передаются основной программой в подпрограмму через стек в виде их копий. Сам параметр программы подпрограммой измениться не может.
- •Параметры-переменные
- •Этот вариант лучше предыдущего, так как в стеке не создается копия исходного массива, что улучшает быстродействие и экономит память.
- •Локализация имен
- •Пример Структура вложенной программы.
- •Основное правило Паскаля
- •Допустимые вызовы процедуры
- •Совместимость и преобразование типов данных
- •Параметры-массивы и строки открытого типа
- •Процедурные типы
- •Проблема совместимости
- •Рекурсия
- •Побочный эффект
- •Рекурсивная функция
- •Стеки для локальных переменных и параметров
- •Реализация стеков параметров в Паскале
Локализация имен
Вывод подпрограммы осуществляется простым упоминанием имени процедуры в операторе вызова процедуры или именем функции в выражении. Каждая процедура или функция описывается в разделе объявлений (заголовок и тело). В заголовке объявляются – имя и формальные параметры. За заголовком следует тело подпрограммы. В разделе объявления подпрограмм могут быть описаны подпрограммы низшего уровня, в них – описание других подпрограмм (вложенные подпрограммы).
Пример Структура вложенной программы.
program first;
procedure A;
procedure A1;
. . . . . . . . . . .
begin
. . . . . . . . . .
end; {A1}
procedure A2;
. . . . . . . . . . . .
begin
. . . . . . . . . .
end; {A2}
begin {A};
. . . . . . . . . . . .
end; {A}
procedure B;
procedure B1;
begin
. . . . . . . . . . .
end; {B1}
procedure B2;
procedure B21;
……………
Все имена, описанные внутри подпрограммы, локализуются в ней, т.е. они «невидимы» снаружи. Другими словами, из основной программы можно обращаться к процедурам А и В, но нельзя вызвать вложенные процедуры А1, А2, В1, В2, В21, В22. Это относиться не только к именам подпрограмм, но и к любым именам, объявленных в них (типам, константам, переменным и меткам). Все имена в пределах подпрограммы, в которой они объявлены, должны быть уникальными и не могут совпадать с именем самой подпрограммы. При входе в подпрограмму низшего уровня становятся доступны не только объявленные в ней имена, но и сохраняется доступ ко всем именам верхнего уровня. Из подпрограммы В21 можно вызвать подпрограмму А, используя имена, объявленные в основных подпрограммах, в подпрограмме В и В2 и затем обращаться к ним.
Пример
program
var v1: . . .;
procedure A;
var v2: . . .;
begin
. . .
end;{A}
procedure B;
var v3: . . .;
procedure B1;
var v4: . . .;
……….
procedure B11;
var v5: . . .;
……………..
Из подпрограммы В11 доступны все 5 переменных v1, v2, v3, v4, v5, из В1 доступно 4 переменных v1, v2, v3, v4. В основной программе доступна всего лишь одна переменная v1.
Основное правило Паскаля
Любая подпрограмма перед использованием должна быть описана. Из В можно вызвать А, но не наоборот (использовать опережающее описание). Подпрограмме доступны только те объекты верхнего уровня, которые описаны до объявления переменных данной программы. Эти объекты являются глобальными по отношению к программе.
В Турбо Паскале допускается произвольная последовательность описания констант, переменных, типов, меток и подпрограмм. Раздел описания переменных var может появляться много раз. Безразличен порядок следования и количество разделов var, const, type, label.
НО При определении области действия этих описаний следует помнить, что имена, описанные ниже по тексту программ, недоступны из ранее описанных подпрограмм.
Пример
var v1: ...;
procedure S;
var v2: ...;
…………..
end {S};
var v3: ...;
…………..
Из процедуры S можно обратиться к переменным v1 и v2, но нельзя использовать v3, т.к. v3 следует в программе за описанием процедуры S.
Имена, локализованные в подпрограмме, могут совпадать с ранее объявленными глобальными переменными. Считается, что локальное имя «закрывает» глобальное, делая его недоступным.
Пример
var
i: integer;
procedure P;
var
i: integer;
begin
writeln(i);
end {P};
begin
i:=1;
P;
end.
Программа печатает всё, что угодно, так как i – не определено. Если описание var i: integer убрать, то будет напечатано значение глобальной переменной 1.
Области действия идентификаторов
program ShowScope;
область
действия x,
y,
z,
Proc1,
Proc2
var x, y, z: real; procedure Proc1;
(m, n, me: real);
область
действия m,
n,
me,
x,
you begin {Proc1} ………… end; {Proc1}
procedure Proc2
(var s, p, x: real);
область
действия s,
p,
x,
Blank,
hi,
bye var hi, bye: string; begin {Proc2} ………… end; {Proc2}
begin {ShowScope} ……………… end. {ShowScope}
|