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

Название «подпрограмма» означает, что она подобна и подчинена программе.

Подпрограммы решают очень важные задачи, значительно облегчая программирование:

избавляют от необходимости многократно повторять в тексте программы аналогичные фрагменты;

улучшают структуру программы, облегчая ее понимание при разборе;

повышают устойчивость к ошибкам программирования и непредвиденным последствиям при модификациях.

Подпрограммы могут быть:

стандартными, т.е. определенными системой Паскаль;

пользовательскими, т.е. разработанными собственно пользователем.

Существует два способа объединения подпрограмм и программ:

текст подпрограмм может быть приведен в разделе описаний использующей их программы до слова begin, с которого начинается тело самой программы(это важно!);

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

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

Второй способ желателен для тех программ, которые составляют Ваш технологический задел по программированию и могут использоваться в других программах. Кроме того, оформление отдельных модулей желательно для больших программ, когда текст становится неудобным для восприятия.

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

Когда Вы несколько раз перепишете в программе одни и те же последовательности команд, необходимость введения подпрограммы приобретет характер острой внутренней потребности.

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

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

Бывают сложные частные алгоритмы. Полезно отладить их отдельно в небольших тестирующих программах. Включение программ с отлаженными алгоритмами в основную программу будет легким, если они оформлены как подпрограммы.

Все, что Вы сделали хорошо в одной программе, Вам захочется перенести в новые. Для повторного использования частей программы лучше сразу выделять полезные алгоритмы в подпрограммы.

Структура текста подпрограммысоответствует структуре текста основной программы:

Следует обратить внимание на два отличия в описании основной программы и подпрограммы:

подпрограмма начинается с заголовка, содержащего имя подпрограммы, передаваемые в нее и возвращаемые от нее параметры. Заголовок подпрограммы отличается от заголовка основной программы;

подпрограмма заканчивается точкой с запятой, а не точкой.

Чем отличаются процедуры и функции?

И процедура, и функция – подпрограмма, которая создается для выделения в отдельный завершенный логический блок некоторого вспомогательного алгоритма. Обычно функция используется в том случае, когда результатом подпрограммы должна быть единственная скалярная (простая) величина. Отличие между процедурой и функцией проявляется также при вызове их из основной программы.

Заголовки процедуры и функции имеют вид:

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

Пример заголовков процедуры и функции:

Procedure primer1 (x, y: real; z: integer);

Function primer2 (n, m: byte): integer;

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

Отличия процедуры от функции связаны со способом вызова.

Для вызова процедурыприводится ее имя и в скобках приводится список передаваемых и получаемых параметров. Вызов процедуры – оператор(это важно!).

Вызов функциипроизводится по ее имени и списку параметров, но, в отличие от процедуры, результат функции имеет определенное значение, поэтому функции используются не как операторы, а как выражения или операнды в выражениях(это важно!). Для того чтобы функция получила численное значение, в теле функции необходимо присвоить ей это значение.

Пример обращения к процедуре и функции:

Primer1 (sin(2),k, 3);

При вызове подпрограммы (процедуры или функции) после ее имени в скобках указываются фактические параметры. Фактическими параметрами могут быть как конкретные значения, так и переменные или даже результат выражения. Последовательность фактических параметров, их количество и их тип должны точно совпадать с формальными параметрами подпрограммы. Значения фактических параметров на момент обращения к подпрограмме должны быть определены.

Передача параметров по ссылке и по значению

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

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

В начале выполнения подпрограммы копии значений этих констант, переменных и выражений присваиваются временным переменным подпрограммы. Когда подпрограмма завершается, используемые в ней переменные не сохраняются. Это значит, что передача параметров по значению имеет смысл для передачи данных в подпрограмму, но не для передачи полученных результатов из нее.

Пример описания формальных параметров, передаваемых по значению:

Procedure primer (x, y: integer; z: real);

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

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

В заголовке процедуры список параметров, принимающих значения по ссылке, начинается служебным словом var.

Пример описания формальных параметров, передаваемых по ссылке:

Procedure primer1 (var k,l: byte; var d: integer);

Решение задачи с использованием подпрограмм

Задача: треугольник задан координатами своих вершин. Составить программу вычисления его площади.

Решение этой задачи удобно представить в виде следующих этапов:

Ввод последовательно координат трех вершин: x1,y1,x2,y2,x3,y3.

Вычисление длины первой стороны

Вычисление длины второй стороны

Вычисление длины третьей стороны

Вычисление площади по формуле Герона

Вывод на экран полученного значения площади.

Из приведенного выше плана решения задачи видно, что в пунктах 2-4 будут выполняться одни и те же действия только с разными координатами вершин. Удобно оформить эти вычисления в виде подпрограммы. Так как длина стороны – это вещественное число, то ее можно вычислять с помощью подпрограммы-функции. При этом для начала можно продумать лишь название функции, ее параметры и тип результата, а детали реализации записать чуть позже. Иначе говоря, следует пока написать «пустую» функцию, чтобы понять для начала ход решения основной задачи.

Итак, пусть наша функция называется storona. Для вычисления стороны треугольника нужно передать в подпрограмму координаты двух вершин. Пусть формальные параметры называютсяa1,b1,a2,b2 и имеют вещественный тип (real). Тип результата функции также будет вещественным.

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

Writeln(‘Введите координаты первой вершины’);

Writeln(‘Введите координаты второй вершины’);

Writeln(‘Введите координаты третьей вершины’);

Writeln(‘площадь треугольника равна:’,s);

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

Для вычисления длины стороны в функции можно описать локальную (определенную только внутри функции) переменную вещественного типа, пусть она называется d.

Function storona (a1, b1, a2, b2: real): real;

D:= sqrt(sqr(a1- a2) +sqr(b1-b2));

Вот теперь наша задача полностью решена.

Эту же задачу можно решить с использованием подпрограммы-процедуры. Начинать решение задачи рекомендуется так же, как и в предыдущем случае. Сначала определить название процедуры, передаваемые в нее параметры, способ получения результата из процедуры. Тело процедуры пока можно сделать пустым. Затем написать основную программу, в которой определить точки обращения к процедуре и значения фактических параметров.

Пусть наша процедура называется dlina. Для вычисления длины стороны треугольника в процедуру необходимо передать значения координат двух вершин, поэтому в списке формальных параметров в заголовке процедуры нужно описать 4 параметра-значения вещественного типа:a1,b1,a2,b2. Для передачи полученного значения в основную программу нужно описать в заголовке параметр-переменную, принимающий ссылку, назовем этот параметрd(необходимо помнить, что в заголовке процедуры перед этим параметром ставится служебное словоvar).

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

Writeln(‘Введите координаты первой вершины’);

Writeln(‘Введите координаты второй вершины’);

Writeln(‘Введите координаты третьей вершины’);

Writeln(‘площадь треугольника равна:’,s);

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

Теперь можно наполнить содержанием саму процедуру:

Procedure dlina (a1, b1, a2, b2: real; var d: real);

D:= sqrt(sqr(a1- a2) +sqr(b1-b2));

Область действия переменных, взаимодействие блоков

В программе может быть описано сколько угодно блоков (подпрограмм). Внутри этих блоков могут быть описания других блоков. Важно знать, откуда и какие блоки могут быть вызваны.

«Блок – это дом с зеркальными стенами. Изнутри видно все, что делается снаружи. Внутрь заглянуть нельзя».

Рассмотрим программу с процедурами различного уровня вложенности. Мы получим иерархию описаний:

Procedure A;

Подпрограмма любого уровня имеет обычно описание множества констант, переменных, типов и вложенных подпрограмм низшего уровня.

Считается, что все имена, описанные внутри подпрограммы, локализуютсяв ней, т.е. они как бы «невидимы» снаружи подпрограммы. Таким образом, со стороны операторов, использующих обращение к подпрограмме, она (подпрограмма) трактуется как «черный ящик», в котором реализуется тот или иной алгоритм. Все детали этой реализации скрыты от глаз пользователя и поэтому недоступны ему.

В рассмотренном выше примере из основной программы можно обратиться к подпрограммам А и В, но нельзя вызвать ни одну из вложенных в них процедур А1, А2, В1, В2 и В21.

При входе в подпрограмму низшего уровня становятся доступными не только описанные в ней имена, но и сохраняется доступ ко всем именам верхнего уровня. Так, например, из подпрограммы В21 мы можем вызвать подпрограмму А, использовать имена, объявленные в основной программе, в подпрограмме В, и обратиться к ним.

При взаимодействии подпрограмм одного уровня вступает в действие основное правило Паскаля: любая подпрограмма перед использованием должна быть описана. Поэтому из процедуры В можно вызвать процедуру А. Из процедуры А вызвать В невозможно (точнее такая возможность появляется только с использованием опережающего описания).

Продолжая образное сравнение, подпрограмму можно уподобить ящику с непрозрачными стенками и дном, но с полупрозрачной крышей: из подпрограммы можно «смотреть» только вверх и нельзя вниз; т.е. подпрограмме доступны только те объекты верхнего уровня, которые описаны до описания данной подпрограммы. Эти объекты называются глобальнымипо отношению к подпрограмме.

Имена локальных переменных могут совпадать с именами глобальных переменных. Если в подпрограмме описана (локализована) переменная с тем же именем, что и глобальная, то в этом случае на время действия подпрограммы локальная переменная «закрывает» глобальную и делает ее недоступной, т.е. значение глобальной переменной на время действия подпрограммы «замораживается».

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

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

Определение

Функция в программировании — подпрограмма, вызываемая из других подпрограмм необходимое число раз.

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

Сравнение

Основная разница между функцией и процедурой — в возвращаемом результате. По сути, и функции, и процедуры представляют собой логически неделимые блоки, из которых складывается код программы. Функция возвращает значение, процедура в большинстве языков программирования — нет, либо (в Си, например) возвращает пустое значение. В последнем случае (в Си) процедура считается подчиненной разновидностью функции.

Заголовок функции содержит слово “function”, идентификатор (собственное имя функции), вариативно список параметров и обязательно — тип результата. В теле функции обязательно прописывается оператор, присваивающий значение имени функции, которое она вернет в качестве результата. Заголовок процедуры содержит слово “procedure”, идентификатор (имя процедуры) и вариативно список параметров. Вызов функции осуществляется в составе выражений там, где эти выражения применяются, вызов процедуры требует отдельного оператора. Вызов процедуры осуществляется только по имени, имя функции же связано с ее значением. На схемах алгоритмов вызов функции изображается в блоке вывода или в блоке процесса, вызов процедуры — в специальном блоке “предопределенный процесс”.

Функция — подпрограмма, выполняющая какие-либо операции и возвращающая значение.
Процедура — подпрограмма, которая только выполняет операции, без возврата значения.
Метод — это функция или процедура, которая принадлежит классу или экземпляру класса.

как бы да, но. только на самом начальном этапе, что бы угомонить хаос в голове новичка ))

в дальнейшем, все интереснее все эти понятия контекстно зависимые, контекстом является парадигма программирования и/или конкретный язык

1 — в контексте парадигм, из данных понятий уникально одно Метод, как уже было сказано D3lphi, это нечто принадлежащее классу. класс, в свою очередь, это фундаментальное понятие ООП основанного на классах (шарм ситуации в том, что ООП бывает тоже разное ;))

в этом случае чаще принято уточнять что метод — это один из видов челнов класса (бывают еще поля, свойства, интерфейсы но это уже контекст конкретного языка) .. и как верно заметил Griboks — он реализуется функцией или процедурой

но .. есть много языков, где понятия метод нет вообще

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

2 — из контекста языков:

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

сейчас доминируют языки, основывающиеся на Си синтаксисе, даже java и js в данном вопросе станут родственниками классического Си

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

смешение всего этого на примере C# — в этом языке, все есть объект. а любой исполняемый код это метод, и методы реализуются только функциями (в тч void функциями)