Назначение подпрограмм
Подпрограммы изначально появились как средство
оптимизации программ по объёму занимаемой памяти — они позволили не
повторять в программе идентичные блоки кода, а описывать их однократно и
вызывать по мере необходимости. К настоящему времени данная функция подпрограмм
стала вспомогательной, главное их назначение — структуризация программы с
целью удобства её понимания и сопровождения.
- Выделение набора действий в
подпрограмму и вызов её по мере необходимости позволяет логически выделить
целостную подзадачу, имеющую типовое решение. Такое действие имеет ещё
одно (помимо экономии памяти) преимущество перед повторением однотипных
действий: любое изменение (исправление ошибки, оптимизация, расширение
функциональности), сделанное в подпрограмме, автоматически отражается на
всех её вызовах, в то время как при дублировании каждое изменение
необходимо вносить в каждое вхождение изменяемого кода.
- Даже в тех случаях, когда в
подпрограмму выделяется однократно производимый набор действий, это
оправдано, так как позволяет сократить размеры целостных блоков кода,
составляющих программу, то есть сделать программу более понятной и
обозримой...
Механизм подпрограмм, их
описание и вызов
В простейшем случае (в ассемблерах) подпрограмма представляет собой
последовательность команд (операторов), отдельную от основной части программы и
имеющую в конце специальную команду выхода из подпрограммы. Обычно подпрограмма
также имеет имя, по которому её можно вызвать, хотя ряд языков программирования
допускает использование и неименованных подпрограмм. В языках высокого уровня
описание подпрограммы обычно состоит по меньшей мере из двух частей: заголовка
и тела. Заголовок подпрограммы описывает её имя и, возможно, параметры,
то есть содержит информацию, необходимую для вызова подпрограммы. Тело —
набор операторов, который будет выполнен всякий раз, когда подпрограмма будет
вызвана.
Вызов подпрограммы выполняется с помощью команды
вызова, включающей в себя имя подпрограммы. В большинстве современных языков
программирования команда вызова представляет собой просто имя вызываемой
подпрограммы, за которым могут следовать фактические параметры (см. ниже).
В следующем примере на языке Паскаль подпрограмма
subprog вызывается из основной программы трижды:
program SubProgExample; // Описание подпрограммы subprog procedure subprog; // Заголовок, включающий имя подпрограммы begin // начало тела подпрограммы WriteLn('Bye'); end; // конец тела подпрограммы begin WriteLn('Hello'); subprog; // 1-й вызов subprog; // 2-й вызов subprog; // 3-й вызов end.
Результатом выполнения такой программы станет
вывод строки «Hello» и трёх строк «Bye».
Некоторые языки программирования (например,
Паскаль, Ада, Модула-2) допускают описание вложенных подпрограмм, то есть
помещение подпрограмм внутрь других подпрограмм. Такие вложенные подпрограммы
могут использоваться только в той подпрограмме, в которой они описаны. В иных
случаях (например, в языке Си) вложение подпрограмм не допускается. Никаких
принципиальных преимуществ вложение подпрограмм не даёт, но может быть удобно
для более логичной структуризации программы (если какая-то подпрограмма
используется только в некоторой другой подпрограмме, логично поместить первую
во вторую).
Параметры подпрограмм
Назначение параметров
Подпрограммы часто используются для многократного
выполнения стереотипных действий над различными данными. Подпрограмма обычно
имеет доступ к объектам данных, описанным в основной программе (по крайней
мере, к некоторым из них), поэтому для того, чтобы передать в подпрограмму
обрабатываемые данные, их достаточно присвоить, например, глобальным
переменным. Но такой путь не особенно удобен и чреват ошибками.
Для обеспечения контролируемой передачи
параметров в подпрограмму и возврата результатов из неё используется механизм параметров.
Параметры описываются при описании подпрограммы (в её заголовке) и могут
использоваться внутри процедуры аналогично переменным, описанным в ней. При вызове процедуры значения
каждого из параметров указываются в команде вызова (обычно после имени
вызываемой подпрограммы).
program SubProgExample2; // Описание подпрограммы subprog procedure subprog(Line: String); // Заголовок, включающий имя подпрограммы begin // начало тела подпрограммы WriteLn(Line); end; // конец тела подпрограммы begin WriteLn('Hello'); subprog('Good bye,'); // 1-й вызов subprog('my love,'); // 2-й вызов subprog('good bye!'); // 3-й вызов end.
В приведённом примере параметр Line
подпрограммы subprog в каждом вызове получает различное значение,
благодаря чему выводятся не одинаковые строки, а разные.
Формальные и фактические
параметры
Чтобы отличать параметры подпрограммы, описанные
в её заголовке и теле, от параметров, указываемых при вызове подпрограммы,
первые принято называть формальными параметрами, вторые — фактическими
параметрами. Так, в последнем примере параметр Line в заголовке и теле
подпрограммы subprog — это формальный параметр, а строка 'Good
bye' , использованная в первом вызове этой подпрограммы — фактический
параметр. При вызове подпрограммы фактические параметры, указанные в команде
вызова, становятся значениями соответствующих формальных параметров, чем и
обеспечивается передача данных в подпрограмму.
Способ передачи
параметров в подпрограмму
Существует несколько способов передачи параметров
в подпрограмму.
- Передача параметров по
значению.
Формальному параметру присваивается значение фактического
параметра. В этом случае формальный параметр будет содержать копию
значения, имеющегося в фактическом, и никакое воздействие, производимое
внутри подпрограммы на формальные параметры, не отражается на параметрах
фактических. Так, если в качестве фактического параметра будет
использована переменная, и внутри подпрограммы значение соответствующего
формального параметра будет изменено, то фактический параметр останется
без изменений.
|