Свойства процедур

1. Что такое подпрограмма?

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

2. Какова суть подпрограммы?

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

3. Какова форма подпрограммы?

По форме подпрограмма есть обобщённый алгоритм, записанный по специальным правилам и не выполняющийся самостоятельно. Подпрограмма может быть вызвана для обработки различных данных, хотя алгоритм обработки один и тот же. Именно в этом смысле этот алгоритм и является обобщённым. Кроме того, алгоритм не является самостоятельным – подпрограмма должна быть вызвана извне.

4. Какими преимуществами обладает подпрограмма?

  1. Использование подпрограмм уменьшает объем исходного кода программы.
  2. Уменьшение исходного кода программы приводит к облегчению процесса тестирования и отладки программы.
  3. Облегчение процесса тестирования и отладки приводит к уменьшению количества ошибок в программе.
  4. Уменьшение исходного кода программы также приводит к повышению читабельность программы, особенно если имена подпрограмм хорошо отражают их смысл.
  5. Повторное использование кода, организованного в подпрограммы, приводит к упрощению и ускорению процесса разработки программы.
  6. Использование вместо большого алгоритма его имени, которое в идеале отражает смысл алгоритма, позволяет абстрагироваться от деталей разработки и упрощает разработку программ на глобальном уровне, что особенно существенно для больших проектов.

5. Что такое процедура?

Процедура – это подпрограмма, которая выполняет некоторые действия, но не возвращает никакого значения.

6. Как объявляется процедура?

При объявлении процедуры необходимо задать имя процедуры и список формальных параметров, которые она будет получать. Эта часть объявления обычно называется заголовком процедуры. После заголовка следует блок, который выполняется при вызове процедуры. Эта часть объявления обычно называется телом процедуры.

7. Как выглядит заголовок процедуры?

procedure <имя процедуры>(<список формальных параметров>);

8. Как выглядит вызов процедуры?

<имя процедуры>(<список фактических параметров>);

9. Что происходит при вызове процедуры?

При вызове процедуры управление передаётся из точки вызова в процедуру, при этом ей передаются указанные фактические параметры. Затем выполняется тело процедуры. По завершении выполнения процедуры управление передаётся обратно в точку вызова. Это означает, что после завершения работы процедуры выполняется оператор, следующий за вызовом процедуры.

10. Как передаются данные в процедуру и из процедуры?

Входные и выходные данные процедуры передаются через параметры. Количество параметров не ограничено, соответственно, процедура может иметь любое количество входных и любое количество выходных параметров. Входные параметры обычно передаются как параметры-значения. Однако использование параметров-констант позволяет компилятору оптимизировать код при передаче данных структурных типов, к которым, в частности, относятся массивы. Поэтому для входных массивов имеет смысл использовать параметры-константы. Выходные параметры передаются через параметры-переменные или выходные параметры.

11. Что такое формальные параметры?

Параметры, записанные в заголовке процедуры, называются формальными. Список формальных параметров – это список неких условных переменных. Он описывает данные, которые должны быть переданы в процедуру, в общем виде.

Список формальных параметров определяется количество, порядок и типы параметров, которые должны быть переданы в процедуру при вызове. Список формальных параметров представляет собой последовательность объявлений, разделённых точкой с запятой, заключённую в круглые скобки. Каждое объявление – это разделяемый запятыми список имён параметров, после которого следует двоеточие и тип. Кроме того, каждому объявлению может предшествовать одно из ключевых слов var, const или out.

12. Что такое фактические параметры?

Параметры, записанные в вызове процедуры, называются фактическими.

Список фактических параметров – это список вполне конкретных значений, которые реально передаются в процедуру и которые она обрабатывает. Формальные параметры – это, в общем-то, абстракция. Фактические параметры должны реально существовать, т.е. это должна быть объявленная и обычно проинициализированная переменная, константа или выражение.

Список фактических параметров представляет собой список выражений, разделённых запятыми. Значения этих выражений подставляются вместо формальных параметров последовательно, т.е. значение первого фактического параметра – вместо первого формального параметра, значение второго фактического параметра – вместо второго формального параметра и т.д.

13. Какая связь между формальными и фактическими параметрами?

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

  1. По количеству. Т.е. если в заголовке процедуры объявлены три формальных параметра, то и фактических параметров должно быть тоже три, не больше и не меньше. Это самый простой критерий, однако, о нём почему-то часто забывают как при разработке программ, так и на экзамене.
  2. По типу. Тип фактического параметра должен либо строго соответствовать типу формального параметра, либо быть совместимым типом. Это зависит от категории параметра – параметр-константа, параметр-значение, параметр-переменная, выходной параметр. Надо помнить о том, что тип в данном случае включает также и структуру переменной, и что компилятор языка Паскаль проверяет соответствие типов по имени.
  3. По порядку следования. Тут возможны две ситуации – отслеживаемая компилятором и не отслеживаемая. Например, если надо передать в процедуру символ и целое число, то попытка передать целое число и символ приведёт к возникновению ошибки. Если же надо передать два целых числа, то компилятор не может отследить правильность их порядка. Но если перепутать местами количество строк и столбцов матрицы, то результат будет неадекватный. Т.е. при передаче параметров надо не только формально учитывать тип, но и смысл каждого параметра.

Имена формальных и фактических параметров совпадать не должны.

14. Что такое параметры-константы?

Параметр-константа – это формальный параметр, объявленный с ключевым словом const. Тип соответствующего фактического параметра должен быть совместимым, в качестве фактического параметра может быть использовано выражение.

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

Параметры-константы структурных и строковых типов используются для оптимизации компилятором кода для передачи этих параметров, т.е. они могут передаваться и по ссылке – это решает компилятор. Параметры-константы базовых типов на эффективность передачи не влияют, они лишь говорят о характере использования такого параметра.

15. Что такое параметры-значения?

Параметр-значение – это формальный параметр, объявленный без использования ключевых слов. Тип соответствующего фактического параметра должен быть совместимым, в качестве фактического параметра может быть использовано выражение.

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

16. Что такое параметры-переменные?

Параметр-переменная – это формальный параметр, объявленный с ключевым словом var. Тип соответствующего фактического параметра должен быть идентичным, в качестве фактического параметра может быть использована только переменная.

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

17. Что такое выходные параметры?

Выходной параметр – это формальный параметр, объявленный с ключевым словом out. Тип соответствующего фактического параметра должен быть идентичным, в качестве фактического параметра может быть использована только переменная.

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

18. Примеры совместимых типов

Формальный параметр Фактический параметр
real single
real integer
double word
integer byte
integer -100..100
byte 0..20
byte shortint (но! отрицательные числа преобразуются в числа от 128 до 255)

19. Примеры выражений

Выражение Описание
x Переменная
15 Целая константа
exp(x) Вызов функции
(a + b) * c Арифметическое выражение
not f Логическое выражение
a[i] Индексное выражение

20. Примеры использования процедур

  1. Определить индексы максимального элемента во всей матрице, в верхней половине матрицы, в нижней половине матрицы, в левой половине матрицы и в правой половине матрицы.
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);
  1. Определить значения k наибольших элементов массива.
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);

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