Обучающий курс. 19. Подпрограммы (часть 1)

Источник: delphi
Еремин Андрей

Введение

Представьте, что у Вас в программе одна и та же последовательность действий повторяется и прописана в разных местах (например, в обработчиках нажатий разных кнопок, выбора пунктов меню и т.п.) Если в программе что-то дублируется, то написана она неверно. Точнее, сам программист не знает о возможностях, которые предоставляет ему язык программирования и/или не знаком с методами оптимизации. Чем плохо дублирование? Вы скажете, код становится более громоздким? Да, в том числе и это, но это не главное. Дело в том, что прямое копирование фрагментов кода сковывает руки и не даёт возможности в дальнейшем делать исправления. Нет, конечно, их можно делать, но если в программе в 100 различных местах написано одно и то же и это "одно и то же" нужно подправить, уйдёт не одна минута на работу, которая, в общем-то, бесполезна. Если речь идёт о каких-то визуальных изменениях программы - это ещё куда ни шло... Представьте другую ситуацию: программа рассчитывает какие-либо данные по заданной формуле. Помимо расчётов программа строит графики, сохраняет информацию в базе данных и т.п. В общем, многофункциональная программа. И в один прекрасный момент выясняется, что формулу расчёта нужно изменить. А у нас она по всей программе задана в явном виде. Придётся исправлять везде. А если где-то забудем исправить, ещё и проблемы возникнут - половина расчётов станут неверными, не те данные попадут в базу данных и т.д. Логично было бы задать формулу расчёта один раз и каким-либо образом её вызывать. Но как? Задать переменную-формулу нельзя... Вот здесь на помощь и приходят подпрограммы.

Подпрограммы

Подпрограмма представляет собой набор операторов, команд, оформленных специальным образом. Подпрограмму можно вызывать из основной программы, причём неограниченное число раз. Вынося какой-то код в подпрограмму, мы исключаем дублирование этого кода в различных местах программы и, естественно, уменьшаем общий объём кода программы. Использование подпрограмм придаёт приложению более структурированную форму. В какой-то степени подпрограммы и упрощают чтение кода для других пользователей. Более того, использование подпрограмм позволяет организовать разделение труда при работе над большим проектом каждый работает над своей задачей, а все результаты быстро и просто подключаются к основной программе.
По структуре подпрограмма практически идентична самой программе - она содержит заголовок, блок описаний, блок реализации. Конечно, форма записи подпрограмм (т.е. их описания) отличается от формы записи самой программы.
В общем случае работа с подпрограммой делится на два этапа. Перво-наперво нужно описать подпрограмму, иначе основная программа просто её не найдёт. После того, как подпрограмма описана, её можно вызывать из основной программы. При этом, конечно, никто не запрещает Вам редактировать подпрограмму и программу параллельно. Т.е. Вы можете сначала просто описать подпрограмму и "повесить" на неё простейшее действие вроде вывода окошка с сообщением, затем прописать вызов подпрограммы во всех нужных местах, протестировать работоспособность программы, и затем продолжить написание подпрограммы.
Вызов подпрограмм осуществляется по их именам. Имя подпрограммы составляется по всем тем правилам, по каким составляются имена идентификаторов (переменных). Т.е. может состоять только из латинских букв, цифр и знака подчёркивания, не может начинать с цифры и т.д. Более подробно правила задания имён идентификаторам были рассмотрены в одном из первых уроков. Имена подпрограмм должны быть уникальными, т.е. не может существовать подпрограмм с одинаковыми именами. Но, как известно, на любое правило есть своё исключение... И здесь есть особые случаи - в объектно-ориентированном программировании (ООП) есть принцип полиморфизма, согласно которому у объектов могут быть методы (они являются подпрограммами) с одинаковыми именами. Но знакомиться с ООП мы будем позже, поэтому не забивайте голову лишними незнакомыми словами :-)
Итак, помимо имени подпрограммы мы должны описать список аргументов (параметров), передаваемых подпрограмме. К примеру, если подпрограмма вычисляет некоторое значение по заданной формуле, параметрами могут являться составляющие переменные, включённые в эту формулу. Допустим, если подпрограмма вычисляет площадь круга, то параметром (аргументом) будет его радиус. Важно отметить, что подпрограммы могут и не иметь входных параметров (т.е. работать без указания всяких данных), а также могут иметь нефиксированное число параметров (т.е. хотите - передавайте один, а хотите - пять, дело Ваше). В третью группу можно выделить подпрограммы, у которых часть параметров обязательна, а часть - нет. Вторые встречаются довольно редко и требуют особого подхода. Каждый параметр - это, по сути, обычная переменная, поэтому при описании параметров нужно каждому из них дать уникальное имя и указать тип данных.
В стандартных модулях Delphi описано великое множество подпрограммы и их можно вызывать без описания. Они уже описаны, просто в других модулях. Помните, мы подключали модуль Math для доступа к математическим функциями? А модуль StrUtils с функциями обработки строк? Так вот, в этих модулях и описаны подпрограммы, которые мы использовали. Если модуль не подключен, Delphi не узнает, где находится подпрограмма и какие функции она выполняет. Но стоит модуль подключить и дополнительный арсенал у нас в кармане. Естественно, помимо использования готовых подпрогрмм мы можем создавать и свои собственные, пользовательские.

Типы подпрограмм

Все подпрограммы делятся на процедуры и функции. В предыдущих уроках эти термины уже использовались. Сейчас Вы узнаете, в чём разница. А различий на самом деле немного. Функция - это подпрограмма, результатом работы которой является какое-либо значение (одно единственное). Это позволяет использовать функции как обычные переменные, т.е. как операнды в выражениях. Просто значения будут вычисляться "на лету". Процедуры - это подпрограммы, которые не возвращают никакого значения в результате своей работы. Тем не менее, процедуры могут использоваться для передачи в основную программу каких-либо данных, причём передаваться может не одно значение, а несколько. Но в общем и целом процедуру следует понимать просто как ярлычок на выполнение указанных действий.

Управление подпрограммами

Вкратце об управлении. Как уже было сказано выше, подпрограммы вызываются по именам. Если подпрограмма требует входные параметры, то они указываются в скобках и разделяются запятыми. С этим мы уже неоднократно встречались, вызывая готовые подпрограммы. Поскольку вызов подпрограммы является отдельной командой, в конце необходим символ ";" (точка с запятой). Если подпрограмма-функция используется как операнд в выражении, точка с запятой, естественно, не нужны - следует воспринимает имя подпрограммы как переменную. Если подпрограмма не требует входных параметров, скобки можно опустить, оставив только имя самой подпрограммы. А можно скобки и написать, просто между ними не будет ничего. Помните, однажды мы учились работать с генератором случаных числе (урок №12)? Там мы вызывали процедуру Randomize для инициализации генератора... Вот у этой процедуры входных параметров нет, поэтому её можно вызвать как Randomize; , так и Randomize(); Лично мне больше нравится писать со скобами - так код становится красивее, да и сразу понятно, что это подпрограмма, а не переменная. Но, повторюсь, писать скобки или нет - дело Ваше. Наконец, можно в любой момент завершить выполнение подпрограммы. Делается это командой Exit (англ. " выход "). Выполнение прерывается в том месте, где находится эта команда. Однако важно помнить, что если Exit находится в функции, то нужно предусмотреть значение, возвращаемое функцией. Завершение выполнения функции совсем не означает, что она не вернёт никакого значения - всё с точностью до наоборот. Помните, что значение любой переменной (а значит и результата работы функции) изначально не определено! Если результатом является число, не думайте, что там записан ноль! Там может быть всё, что угодно.

Заключение

Сегодняшний урок носит в основном теоретический характер. Мы не рассматривали никаких конкретных примеров и пока что не учились создавать свои подпрограммы. Этим мы займёмся в следующий раз. Сейчас важно понять назначение подпрограмм и усвоить основную терминологию, которая используется при работе с ними. Далее, когда перейдём к практике, всё станет более понятным.

Домашнее задание

Определить, какие входные параметры было бы логично задать для следующих подпрограмм:

  1. Функция, считающая, сколько раз буква встречается в тексте.
  2. Функция, вычисляющая объём цилиндра.
  3. Функция, проверяющая, является ли параллелепипед кубом.
  4. Процедура, делающая 3 кнопки, расположенные на форме, недоступными для нажатия.
  5. Процедура, изменяющая разрешение экрана.

Страница сайта http://test.interface.ru
Оригинал находится по адресу http://test.interface.ru/home.asp?artId=22534