На этом шаге мы рассмотрим еще несколько "хитрых" моментов, связанных с подпрограммами.
Иногда встречаются случаи, когда две подпрограммы содержат вызовы друг друга, например:
Procedure ab(x,y: Real);
Begin
. . .
cd (1,2);
. . .
End;
Procedure cd(i,j: Integer);
Begin
. . .
ab(3.4,5.5);
. . .
End;
При трансляции процедуры AB компилятор не сможет правильно обработать вызов процедуры CD, так как она описана ниже и компилятору неизвестна. Если процедуры поменять местами, то аналогичная ситуация возникнет с процедурой CD.
Решением этой проблемы является механизм предварительных описаний подпрограмм. Предварительное описание содержит заголовок подпрограммы, а вместо тела записывается служебное слово Forward, которое указывает, что полное описание подпрограммы располагается в тексте далее. В этом случае заголовок полного описания может быть записан в сокращенном виде, без списка параметров и без типа результата для функций. Перепишем последний пример:
Procedure ab(x,y: Real); Forward;
Procedure cd(i,j: Integer); Forward;
. . .
Procedure ab;
Begin
. . .
cd (1,2);
. . .
End;
Procedure cd;
Begin
. . .
ab(3.4,5.5);
. . .
End;
Здесь при вызове процедуры CD компилятор использует информацию об этой процедуре из заголовка предварительного описания.
Другим специальным случаем задания тела подпрограммы является так называемое внешнее описание. В этом случае подпрограмма, как правило, разработана вне системы Turbo Pascal на другом языке (как правило, на языке ассемблера) и необходимо ее подключить к Pascal-программе. В этом случае объектный код содержится в некотором OBJ-файле, а само подключение производится следующим образом.
В Pascal-программе указывается заголовок подключаемой подпрограммы, после которого вместо тела подпрограммы располагается служебное слово External. Кроме этого, где-то в тексте программы необходимо задать директиву компилятора {$L}, после которой располагается имя OBJ-файла, содержащего код подключаемой программы, например:
Procedure Prog1(a,b,c:Integer); External;
Procedure Prog2(x,y:Real); External;
. . .
{$L PROG.OBJ}
Для корректного подключения необходимо соблюдать определенные межязыковые соглашения,
принятые в языке программирования Pascal. Эту информацию можно найти в документации.
На следующем шаге мы приведем решение нескольких задач, где используется разобранный
механизм подпрограмм.