Процедура вызывается указанием ее имени, которое записывается после зарезервированного слова Procedure, используемого для обозначения процедуры.
Begin Procedure Sum (х,у: Integer; Var z: Integer);
... Begin
ReadLn (a,b); z:=x+y;
Sum (a, b, c); End;
WriteLn (c) ;
End
Линейный ход выполнения основной программы становится нелинейным — управление вычислительным процессом передается на участок программного кода, занимаемый процедурой. После выполнения процедуры осуществляется возврат на оператор основной программы, следующий за вызовом процедуры (End; в процедуре очень содержательный оператор, сверхсодержательный — это «стрелка», возврат управления в логику, из которой вызывается процедура). Мы не рассматриваем вопросы о том, как это выполняется. Например, как осуществляется возврат на оператор WriteLn(c). Наше объяснение идет на уровне констатации фактов, и только. Итак, взаимодействие программы и процедуры по управлению мы обозначили. Перейдем к взаимодействию по данных. В программе определены переменные а, b, с. В процедуре — х, у, z её параметры, но они являются переменными процедуры. Причем х, у описаны без идентификатора Var, а c — с идентификатором Var. Поясним разницу.
При вызове процедуры Sum(a,b,c) из основной программы значение переменной а присваивается переменной х процедуры Sum, а значение переменной b становится значением переменной у, и все. Стрелочка на рисунке в одну сторону. Чуть сложнее с переменными с и z . Образно выражаясь, процедура Sum знает о том, где в памяти компьютера находится переменная с, и она знает, что при изменении значения переменной z необходимо произвести соответствующее изменение значения переменной с. Это обратная связь по данным от процедуры к основной программе. На такой тип связи указывает идентификатор Var в описании параметров процедуры.
Перейдем к ряду стандартных определений. В любой программе все переменные делятся на глобальные и локальные. В нашем фрагменте программы переменные а, b, с — глобальные, а x, у, z — локальные. Глобальные переменные — это переменные из раздела описаний основной части программы, а локальные — из раздела описаний процедур и функций. Если разница только в месте описания переменных, то «стоит ли шкурка выделки»? Добавим ещё одно предложение. Локальные переменные существуют только в течение времени работы процедуры, определяются (создаются) при её вызове и исчезают после завершении работы процедуры (после выполнения «сверхсодержательного» оператора End;). Таким образом, если бы в основной программе было три фрагмента с вызовом процедуры Sum (желательно с различными параметрами), то для программного кода процедуры Sum три раза выделялось место в оперативной памяти, соответственно, и для переменных х, у, z и три раза
освобождалось. Если такое объяснение облегчает понимание разницы между глобальными и локальными переменными, то считаем его правильным.
Параметры. При описании процедуры указывается список формальных параметров. Каждый параметр является локальным по отношению к описываемой процедуре, к нему можно обращаться только в пределах данной процедуры (в нашем примере х, у, z — формальные параметры). Фактические параметры — это параметры, которые передаются процедуре при обращении к ней (а, b, с — фактические параметры). Число и тип формальных и фактических параметров должны совпадать с точностью до их следования.
Параметры-значения. Другими словами, передача параметров по значению. Копия фактического параметра становится значением соответствующего формального параметра. Внутри процедуры можно производить любые действия с данным формальным параметром (допустимые для его типа), но эти изменения никак не отражаются на значении фактического параметра, то есть каким он был до вызова процедуры, то таким же и останется после завершения ее работы (х, у — параметры-значения).
Параметры-переменные. Другими словами, передача параметров по ссылке. Это те формальные параметры, перед которыми стоит идентификатор Var. Передается адрес фактического параметра (обязательно переменной), после этого формальный параметр становится его синонимом. Любые операции с формальным параметром выполняются непосредственно над фактическим параметром.
Договоримся о том, как мы будем стараться использовать процедуры, может быть, в ущерб эффективности программ, например, с точки зрения количества переменных и т. д. Каждая процедура должна иметь одну точку входа и одну точку выхода, использование глобальных переменных в процедуре должно быть минимально, взаимодействие вызывающей логики с процедурой должно осуществляться (по возможности) только через параметры. Зачем нам эти оговорки? Мы осваиваем структурную технологию разработки программ, при этом на каждом этапе текущая задача разбивается на ряд подзадач, определяя тем самым некоторое количество отдельных подпрограмм (подпрограмма — это повторяющаяся группа операторов, оформленная в виде самостоятельной программной единицы). При этом мы стараемся структурировать задачу не только по управлению, но и по данным, используя при этом весьма ограниченный набор инструментов (параметры-значения, параметры-ссылки). Концепция процедур и функций — один из механизмов второго витка развития технологий программирования, а именно, структурного проектирования.
Описание функции.Функция выглядит почти так же, как и процедура. Почти единственное отличие в том, что заголовок функции начинается с ключевого слова Function и кончается типом возвращаемого данной функцией значения.
Function <имя функции> [(список параметров)] : <тип результата>;
Кроме того, в теле функции обязательно должен быть хотя бы один оператор присвоения, где в левой части стоит имя функции, а в правой — ее значение. Иначе значение функции не будет определено.