Процедуры в языке 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.

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

Задания для дополнительной или самостоятельной работы:

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