Процедуры в языке Pascal
Создано: 21.04.2026
Все действия, которые мы ранее выполняли с данными, осуществлялись либо операторами языка программирования, либо функциями и процедурами как встроенными в него, так из его стандартной библиотеки. И если в Паскале свой новый оператор мы создать не можем, то создать свою функцию или процедуру — вполне. Такие будут называться "пользовательскими", или "внешними", или "собственными", то есть они не стандартные.
Функции и процедуры вместе называются подпрограммами. Такое название у них не с проста, а потому что их можно представить как маленькие самостоятельные программки. Они достаточно автономны, независимо исполняют свой код, могут принимать данные в себя и отдавать из себя как настоящие программы. Единственное, что их отличает от полноценной программы, — они не могут без нее запускаться. Приказы на исполнение подпрограммам отдает программа.
У многих других языков программирования нет процедур, есть только функции, поэтому понятия "подпрограмма" и "функция" в них — одно и то же. Мы же, изучая Pascal, начнем знакомство с подпрограммами именно с процедур, потому что они несколько проще функций.
Допустим, что нужен код, который извлекает из строки цифры и находит их сумму. Пойдем привычным нам путем и напишем весь код в разделе действий самой программы:
var s: string; i, d: byte; sum: word; begin read(s); sum := 0; for i:=1 to length(s) do if (s[i] >= '0') and (s[i] <= '9') then begin val(s[i], d); sum := sum + d; end; writeln(sum); end.
Пример выполнения:
3abc 78de11 20
Теперь представьте, что программа большая, и этот код требуется в нескольких ее местах. Конечно, мы можем просто скопировать его туда. Однако если мы захотим поменять что-то в коде, например вычислять сумму не цифр, а именно чисел (в примере выше цифры — это 3, 7, 8, 1, 1, а числа — 3, 78, 11), то надо будет найти все вставки этого кода, чтобы его поменять. Это неудобно и может приводить к ошибкам.
Поэтому разумным решением будет вынести решающий определенную задачу код отдельно, дать ему имя, а когда надо его исполнить, вызывать по имени. Сделаем это:
var s: string; procedure DigitSum(str: string); var sum: word; i, d: byte; begin sum := 0; for i:=1 to length(str) do if (str[i] >= '0') and (str[i] <= '9') then begin val(str[i], d); sum := sum + d; end; writeln(sum); end; begin read(s); DigitSum(s); end.
Итак, мы создали процедуру под именем DigitSum. У нее есть свой блок var и свой блок действий, заключенный в begin-end. Поэтому она похожа на программу, которая находится внутри большой программы. На практике может быть определено много разных процедур и функций, и чтобы не "засорять" код основной программы, их выносят в отдельный файл–модуль, который подключают к главному файлу программы.
Код основной программы у нас состоит всего из двух выражений: read(s); DigitSum(s);. Во втором мы вызываем процедуру, обращаясь к ней по имени. Это заставляет ее исполняться один раз. Когда процедура вызывается, ей в скобках мы передаем значение переменной s. Обратите внимание, не саму переменную, а данные из этой переменной, то есть конкретную введенную ранее строку. В процедуре эти данные присваиваются переменной str, и далее процедура работает только с этой, своей, переменной.
Когда подпрограмма вызывается, то, что ей передается в скобках, в Паскале называется фактическим параметром. Переменная, которая объявлена в скобках заголовка подпрограммы, называется формальным параметром. В других языках программирования их могут называть аргументом и параметром соответственно. Или, не делая различий, все называть аргументами или параметрами.
Фактическим параметром не обязательно должна быть переменная, это может быть "голый" литерал–значение, который в подпрограмме будет присвоен ее формальному параметру:
DigitSum('a4b5yes04');
Параметров может не быть вообще или больше одного. Пример процедуры, которая принимает два числа и выводит на экран их среднее арифметическое:
var a, b: integer; procedure Mean(n1, n2: integer); begin writeln((n1 + n2) / 2 :0:2); // 478.50 end; begin read(a, b); // 345 612 Mean(a, b); end.
Измените процедуру Mean так, чтобы она не имела параметров, но вся программа работала бы также.
Если формальные параметры имеют разный тип данных, то в скобках они объявляются отдельно друг от друга и между ними ставится точка с запятой. Например:
procedure MyProc(x: integer; str: string);
Когда в программе появляются процедуры и функции, то вместе с ними возникают такие понятия как локальная и глобальная области видимости, а также локальные и глобальные переменные. Локальные переменные объявляются в разделе var подпрограммы. Они и формальные параметры видны только внутри своих подпрограмм. К ним нельзя обратиться извне, из кода самой программы. Глобальные переменные объявляются в главной программе. К ним можно обращаться не только из основного раздела begin-end, также из кода подпрограмм.
Напишите код, который доказывает, что локальные переменные недоступны в главной программе.
Зная, что глобальные переменные доступны отовсюду, мы могли бы переписать первый пример этого урока так, чтобы все переменные были глобальными, и мы бы обращались к ним из кода процедуры:
var s: string; sum: word; i, d: byte; procedure DigitSum; begin sum := 0; for i:=1 to length(s) do if (s[i] >= '0') and (s[i] <= '9') then begin val(s[i], d); sum := sum + d; end; writeln(sum); end; begin read(s); DigitSum(); end.
Однако делать так плохо. Это нарушает принцип структурного программирования, лишает подпрограмму ее автономности. Представьте, что процедура вынесена в отдельный модуль, который мы подключаем то к этому проекту, то к другому. В каждом пришлось бы объявлять необходимые переменные и предварительно изучать процедуру, чтобы понять какие нужны. В то время как локальные переменные делают подпрограмму в достаточной степени независимой, чтобы пользоваться ей, не обязательно знать, как она работает внутри. Достаточно знать только то, что надо в нее передать и каков результат ее работы.
Задания для дополнительной или самостоятельной работы:
Разработайте программу с процедурой, формальным параметром которой является символьная переменна. В процессе своего выполнения процедура должна выдавать случайное число и выводить на экран переданный ей символ в количестве сгенерированного числа. В коде основной программы в цикле, который совершает три повтора, вызовите процедуру, каждый раз передавая в нее иной фактический параметр.