Список параметров
Описание подпрограммы
Объявление процедуры
Объявление функции
Объявление и описание
Подпрограммы объявляются и описываются в начале Pascal-программы, до ключевого слова begin, означающего начало тела программы.
Различия между процедурами и функциями начинаются уже с момента их объявления.
Функции объявляются следующим образом:
function <имя_функции> [(<список_параметров>)]:<тип_результата>;
В отличие от констант и переменных, объявление подпрограммы может быть оторвано от ее описания. В этом случае после объявления нужно указать ключевое слово forward:
function <имя_функции> [(<параметры>)]:<тип_результата>; forward;
Процедуры следует объявлять так:
procedure <имя_процедуры> [(<список_параметров>)];
Если объявление процедуры оторвано от ее описания, нужно поставить после него ключевое слово forward:
procedure <имя_процедуры> [(<список_параметров>)]; forward;
Описание подпрограммы должно идти после ее объявления. Оно осуществляется по следующей схеме (единой для процедур и функций):
[ uses <имена_подключаемых_модулей>;]
[ label <список_меток>;]
[ const <имя_константы> = <значение_константы>;]
[ type <имя_типа> = <определение_типа>;]
[ var <имя_переменной> : <тип_переменной>;]
[ procedure <имя_процедуры> <описание_процедуры>]
[ function <имя_функции> <описание_функции>;]
begin {начало тела подпрограммы}
<операторы>
end; (* конец тела подпрограммы *)
Если объявление подпрограммы было оторвано от ее описания, то описание начинается дополнительной строкой с указанием только имени подпрограммы:
function <имя_подпрограммы>;
или
procedure <имя_подпрограммы>;
Описания двух различных подпрограмм не могут пересекаться: каждый блок должен быть логически законченным. Однако внутри любой подпрограммы (она ведь тоже является программой) могут быть описаны другие процедуры или функции - вложенные. На них распространяются все те же правила объявления и описания подпрограмм.
Пример подпрограммы-процедуры:
procedure err(c:byte; s:string);
var zz: byte;
begin if c = 0
then writeln(s)
else writeln('Ошибка!')
end;
В заголовке подпрограммы (в ее объявлении) указывается список формальных параметров переменных, которые принимают значения, передаваемые в подпрограмму извне во время ее вызова. Для краткости мы далее будем опускать слово "формальный".
Поскольку внутри подпрограммы параметры рассматриваются как переменные с начальным значением, то имена локальных переменных, описываемые в разделе var (внутреннем для подпрограммы), не могут совпадать с именами параметров этой же подпрограммы. Подробнее о локальных и глобальных переменных мы расскажем в пункте "Разграничение контекстов".
Список параметров может и вовсе отсутствовать:
procedure proc1;
function func1: boolean;
В этом случае подпрограмма не получает никаких переменных "извне" (в которую не передается никаких данных при вызове).
Однако отсутствие параметров и, как следствие, передаваемых извне значений вовсе не означает, что при каждом вызове подпрограмма будет выполнять абсолютно одинаковые действия. Поскольку глобальные переменные видны изнутри любой подпрограммы, их значения могут неявно изменять внутреннее состояние подпрограмм. Этому очень нежелательному эффекту будет посвящен пункт "Побочный эффект".
Если же параметры имеются, то каждый из них описывается по следующему шаблону:
[<способ_подстановки>]<имя_параметра>:<тип>;
О возможных способах подстановки значений в параметры (<пустой>, var, const) мы расскажем в разделе "Способы подстановки аргументов".
Если способ подстановки и тип нескольких параметров совпадают, описание этих параметров можно объединить:
[<способ_подстановки>]<имя1>,...,<имяN>: <тип>;
Пример описания всех трех способов подстановки:
function func2(a,b:byte; var x,y,z:real; const c:char) : integer;
В заголовке подпрограммы можно указывать только простые (не составные) типы данных. Следовательно, попытка записать
procedure proc2(a: array[1..100]of char);
вызовет ошибку уже на этапе компиляции. Для того чтобы обойти это ограничение, составной тип данных нужно описать в разделе type, а при объявлении подпрограммы воспользоваться именем этого типа:
type arr = array[1..100] of char;
procedure proc2(a: arr);
function func2(var x: string): arr;