Подпрограмма – это записанный отдельно и поименованный алгоритм, решающий определённую задачу, которому можно передавать данные для обработки. Подпрограмма или процедура – это одно из фундаментальных средств структурного программирования. Недаром подобные Паскалю языки программирования называются процедурными.
По сути, подпрограмма есть средство абстракции, позволяющее именовать последовательность действий и при необходимости выполнения этой последовательности обращаться к ней по имени.
По форме подпрограмма есть обобщённый алгоритм, записанный по специальным правилам и не выполняющийся самостоятельно. Подпрограмма может быть вызвана для обработки различных данных, хотя алгоритм обработки один и тот же. Именно в этом смысле этот алгоритм и является обобщённым. Кроме того, алгоритм не является самостоятельным – подпрограмма должна быть вызвана извне.
Процедура – это подпрограмма, которая выполняет некоторые действия, но не возвращает никакого значения.
При объявлении процедуры необходимо задать имя процедуры и список формальных параметров, которые она будет получать. Эта часть объявления обычно называется заголовком процедуры. После заголовка следует блок, который выполняется при вызове процедуры. Эта часть объявления обычно называется телом процедуры.
procedure <имя процедуры>(<список формальных параметров>);
<имя процедуры>(<список фактических параметров>);
При вызове процедуры управление передаётся из точки вызова в процедуру, при этом ей передаются указанные фактические параметры. Затем выполняется тело процедуры. По завершении выполнения процедуры управление передаётся обратно в точку вызова. Это означает, что после завершения работы процедуры выполняется оператор, следующий за вызовом процедуры.
Входные и выходные данные процедуры передаются через параметры. Количество параметров не ограничено, соответственно, процедура может иметь любое количество входных и любое количество выходных параметров. Входные параметры обычно передаются как параметры-значения. Однако использование параметров-констант позволяет компилятору оптимизировать код при передаче данных структурных типов, к которым, в частности, относятся массивы. Поэтому для входных массивов имеет смысл использовать параметры-константы. Выходные параметры передаются через параметры-переменные или выходные параметры.
Параметры, записанные в заголовке процедуры, называются формальными. Список формальных параметров – это список неких условных переменных. Он описывает данные, которые должны быть переданы в процедуру, в общем виде.
Список формальных параметров определяется количество, порядок и типы параметров, которые должны быть переданы в процедуру при вызове. Список формальных параметров представляет собой последовательность объявлений, разделённых точкой с запятой, заключённую в круглые скобки. Каждое объявление – это разделяемый запятыми список имён параметров, после которого следует двоеточие и тип. Кроме того, каждому объявлению может предшествовать одно из ключевых слов var, const или out.
Параметры, записанные в вызове процедуры, называются фактическими.
Список фактических параметров – это список вполне конкретных значений, которые реально передаются в процедуру и которые она обрабатывает. Формальные параметры – это, в общем-то, абстракция. Фактические параметры должны реально существовать, т.е. это должна быть объявленная и обычно проинициализированная переменная, константа или выражение.
Список фактических параметров представляет собой список выражений, разделённых запятыми. Значения этих выражений подставляются вместо формальных параметров последовательно, т.е. значение первого фактического параметра – вместо первого формального параметра, значение второго фактического параметра – вместо второго формального параметра и т.д.
Список фактических параметров должен соответствовать списку формальных параметров по следующим критериям.
Имена формальных и фактических параметров совпадать не должны.
Параметр-константа – это формальный параметр, объявленный с ключевым словом const. Тип соответствующего фактического параметра должен быть совместимым, в качестве фактического параметра может быть использовано выражение.
Параметр-константа ведёт себя как локальная константа. Параметры-константы сходны с параметрами-значениями, но в теле процедуры нельзя изменить параметр-константу и нельзя передать её в другую процедуру в качестве параметра-переменной.
Параметры-константы структурных и строковых типов используются для оптимизации компилятором кода для передачи этих параметров, т.е. они могут передаваться и по ссылке – это решает компилятор. Параметры-константы базовых типов на эффективность передачи не влияют, они лишь говорят о характере использования такого параметра.
Параметр-значение – это формальный параметр, объявленный без использования ключевых слов. Тип соответствующего фактического параметра должен быть совместимым, в качестве фактического параметра может быть использовано выражение.
Параметр-значение ведёт себя как локальная переменная, которая инициализируется значением, передаваемым при вызове процедуры. Если в качестве параметра-значения передаётся переменная, то компилятор создаёт её копию, и процедура работает именно с копией. Изменения копии никак не влияют на исходную переменную. Если в качестве параметра-значения передаётся выражение, которому вообще не может быть присвоено новое значение, компилятор записывает его значение в специально выделенную область памяти, и процедура работает с этой областью памяти. После завершения работы процедуры копия переменной или выделенная область памяти освобождаются.
Параметр-переменная – это формальный параметр, объявленный с ключевым словом var. Тип соответствующего фактического параметра должен быть идентичным, в качестве фактического параметра может быть использована только переменная.
Параметр-переменная ведёт себя как указатель на переменную, являющуюся фактическим параметром. Все действия, производимые процедурой, производятся именной над переменной, являющейся фактическим параметром. Соответственно процедура может изменить значение этой переменной.
Выходной параметр – это формальный параметр, объявленный с ключевым словом out. Тип соответствующего фактического параметра должен быть идентичным, в качестве фактического параметра может быть использована только переменная.
Выходные параметры, как и параметры-переменные, передаются в процедуру по ссылке. Отличие состоит в том, что выходные параметры рассматриваются именно как выходные, и значение переменной, являющейся фактическим параметром, игнорируется.
Формальный параметр | Фактический параметр |
---|---|
real | single |
real | integer |
double | word |
integer | byte |
integer | -100..100 |
byte | 0..20 |
byte | shortint (но! отрицательные числа преобразуются в числа от 128 до 255) |
Выражение | Описание |
---|---|
x | Переменная |
15 | Целая константа |
exp(x) | Вызов функции |
(a + b) * c | Арифметическое выражение |
not f | Логическое выражение |
a[i] | Индексное выражение |
procedure IndexesOfMax(const x: matrix; ms, me, ns, ne: integer; var imax, jmax: integer);
...
IndexesOfMax(a, 1, m, 1, n, imax, jmax);
IndexesOfMax(a, 1, m div 2, 1, n, imax, jmax);
IndexesOfMax(a, m div 2 + 1, m, 1, n, imax, jmax);
IndexesOfMax(a, 1, m, 1, n div 2, imax, jmax);
IndexesOfMax(a, 1, m, n div 2 + 1, n, imax, jmax);
procedure KMax(x: mas; n: integer; var m: mas; k: integer);
var
im, i, j: integer;
begin
for j := 1 to k do
begin
im := j;
for i := im + 1 to n do
if x[i] > x[im] then
im := i;
m[j] := x[im];
x[im] := x[j];
x[j] := m[j];
end;
end;
...
KMax(a, n, m3, 3);
KMax(a, n, m5, 5);
Обратите внимание, что в данном примере для передачи массива в процедуру не использовался параметр-константа, т.к. мы меняем массив, переставляя его элементы, чтобы «отложить» уже найденный максимум. Однако, поскольку используется параметр-значение, эти изменения не будут переданы из процедуры.