Процедуры

procedure somename(x:integer); // Процедура выводит на экран целое значение x, умноженное на 10.0 // в указанном формате. // // Написана довольно давно неизвестным программистом // // Такой комментарий, содержащий // цель написания процедуры (что она делает и зачем нужна), // данные о времени написания и об авторе, // описания параметров, // особенности алгоритма // полезно включать в код любой процедуры var // Локальные переменные - могут использоваться только внутри данной процедуры! y: real; begin // Раздел кода процедуры y := 10.0; x := x * y; write(x:10:1); end;

В данном примере выводится значение x, которое является параметром, умноженное на 10, в формате минимум 10 знаков и с точностью до десятых (одна цифра после десятичной точки).

В качестве параметра x может быть подано любое выражение, совместимое с указанным в описании типом параметра x, т.е. integer.

Функции

function somename(x:integer):real; var y: real; begin y := 10.0; somename := x * y; end;

Использование глобальных и локальных объектов, а также параметров

Локальные и глобальные объекты

В приведённом выше примере видно, что в процедурах можно описывать переменные. Внутри процедур можно описывать и другие объекты — вложенные процедуры и функции, типы, константы и метки. Общим для них является то, что их нельзя использовать нигде вне той процедуры, где они описаны. Поэтому они называются локальными.

Всё, что описано вне процедур, а именно — в самой программе, импортировано из других модулей с помощью предложения uses, а также — системные объекты, вроде процедуры writeln или типа integer, называется глобальными объектами.

Локальные переменные

Необходимость в локальных константах и типах возникает редко, в локальных метках — ещё реже, а использовать вложенные процедуры вообще не рекомендуется из-за усложнения структуры программы. Таким образом, важнейшими локальными объектами являются локальные переменные.

Во время выполнения программы, при каждом вызове процедуры под локальные переменные автоматически выделяется участок памяти, который используется процедурой под локальные переменные. После окончания её работы, память возвращается системе и может быть использована в новых целях. Например, для размещения локальных переменных другой процедуры. Таким образом, можно заметить следующее:

между вызовами конкретной процедуры все её локальные переменные просто не существуют и любые попытки обратиться к ним по именам являются синтаксической ошибкой, а попытки обратиться по адресам — опасны;

при рекурсивных вызовах процедур, когда процедура вызывает сама себя, одновременно существует несколько экземпляров одной и той же переменной;

локальные неинициализированные переменные, т.е. не получившие явного начального значения, могут содержать не только нулевые значения, но и любой другой «мусор»;

значения локальных переменных между вызовами не сохраняются.

var i,j : integer; // Глобальные переменные procedure P1; // Началось описание процедуры P1 var // k : integer; // к - локальная переменная в P1 // procedure P2; // Вложенная процедура P2 var // n : integer; // n - локальная переменная в P2 // begin // Начался код P2 ... // end; // P2 - закончилась // begin // Начался код P1 ... // P2; // Вызов P2 ... // end; // P1 - закончилась var m,l:integer; // Продолжение описаний глобальных переменных. // Необходим новый раздел // begin // Начался код самой программы ... // P1; // Вызов P1 внутри программы ... // end. // Вся программа закончилась

Типизированые константы

Важнейшими локальными объектами являются локальные переменные. Описываемая возможность используется относительно редко. Если необходимо сохранить значение между вызовами процедуры, можно использовать типизованные константы. Не смотря на название, каждая типизованная константа является переменной!!! Её значение можно менять, а также использовать всюду, где язык Паскаль требует использования переменных. Особенностью данных переменных является то, что исходное значение они получают сразу после начала работы программы и сохраняют его до тех пор, пока оно не будет изменено.

Function F:integer; // синтаксически правильная бессмысленная функция с ужасным кодом и логической ошибкой. var i : integer; const o = 0; // обычная константа tConst : integer = 10; // Типизированная константа begin for i := o to tConst do F := // Последнее значение переменной F определяет, // какое значение вернёт функция F после вызова F + i; // Здесь F - рекурсивный вызов функции F внутри // функции F if tConst > 0 then dec(tConst); end;

Правила видимости

В языке Паскаль

Параметры

Считается правильным, когда процедура(функция) не обращается скрытым образом к объектам, описанным вне её — в программе или других процедурах и функциях. По крайней мере, она не должна их скрытым образом менять. Если необходимо получить доступ к внешним данным, а тем более их изменить, то рекомендуется делать это явным образом - через передачу в качестве параметров.

Различают формальные и фактические параметры.

Различают способы передачи параметров — передачу по значению и передачу по ссылке.

Формальные и фактические параметры

При вызове процедуры, в качестве параметров подставляются конкретные константы, переменные или выражения. Их обрабатывает процедура в соответствии со своим алгоритмом. То, что фактически подставляется в качестве параметров, так и называется — фактическими параметрами Ещё фактические параметры часто называют аргументами.

В заголовках процедур описываются специальные имена. В дальнейшем, эти имена используются для описания алгоритма работы процедуры так, будто это реальные переменные. Эти переменные называются формальными параметрами. Имена формальных параметров не имеют значения. Важен их порядок перечисления в заголовке процедуры и иногда приписанный им тип.

Типы формальных и фактических параметров должны соответствовать друг другу, а в некоторых случаях должны точно совпадать.

Передача по значению

Если перед формальным параметром НЕ стоит префикс «var», то говорят, что аргумент передаётся процедуре по значению. Это означает, что компилятором создаётся следующий код:

вначале вычисляется значение аргумента,

затем в области стека создаётся временная переменная указанного в заголовке процедуры типа,

если возможно,

ей присваивается вычисленное значение,

а в противном случае - компилятором выдается сообщение об ошибке.

Таким образом, параметр, передаваемый по значению похож на локальную переменную. Такие параметры называют параметрами-значениями.

В качестве параметров-значений можно подставлять любые выражения подходящего типа, в том числе — константные значения, именованные константы, вызовы функций и переменные.

procedure badswap(a,b:integer); var t:integer; begin t := a; a := b; b := t; end;

Передача по ссылке

Если перед формальным параметром стоит префикс «var», то говорят, что аргумент передаётся процедуре по ссылке. Это означает, что процедура работает с реальным объектом. Соответственно, все изменения этого объекта сохранятся в программе. Такие параметры называются параметрами -переменными

procedure goodswap(var a,b:integer); // Нормально работающая процедура обмена значениями переменных. var t:integer; begin t := a; a := b; b := t; end;