Массивы в процедурах и функциях языка Pascal

Обновлено: 25.04.2026

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

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

Рассмотрим программу, в которой целочисленный массив выводится на экран с помощью процедуры:

const
    N = 10;
type
    myArray = array[1..N] of Integer; 
var
    a: myArray;
    i: Byte;

procedure writeA(b: myArray);  
begin
    for i:=1 to N do 
        write(b[i], ' ');
    writeln;
end;

begin
    randomize;
    for i:=1 to N do
        a[i] := random(100) - 50;

    writeA(a);
end.
-40 -2 -24 42 18 -43 24 -28 48 -16

В ней мы создаем свой тип данных myArray и далее используем его при определении глобальной переменной a и параметра b процедуры. Если в случае с переменной можно было бы не использовать пользовательский тип и определить ее обычным способом, то с параметром так сделать не получится. При этом лучше, чтобы тип переменной совпадал по имени с типом параметра, и упоминание в обоих случаях myArray подчеркивает их однотипность.

Создадим в этой же программе функцию, которая заполняет массив:

...
function randA(b: myArray): myArray;  
begin
    randomize;
    for i:=1 to N do
        b[i] := random(100) - 50;
    randA := b;
end;
...
begin
    a := randA(a);
    writeA(a);
end.

Теперь зададимся вопросом, сколько на самом деле массивов у нас существует в программе в момент выполнения функции? Вспомним, что ранее мы говорили, что фактический параметр передается в подпрограмму по значению, и это значение присваивается формальному параметру. Поэтому, когда выполняется вызов функции randA(a) массив копируется и присваивается переменной b. Исходно массив a заполнен нулями. Но он существует, а значит, занимает память. Если представить, что массив состоит не из 10 элементов, а из тысяч, то расход памяти на второй, то есть b, будет уже существенным.

Подумайте, почему в представленном коде в момент выполнения функции на самом деле существует не два, а три однотипных массива?

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

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

...
procedure randA;  
begin
    randomize;
    for i:=1 to N do
        a[i] := random(100) - 50;
end;
...
begin
    randA();
    writeA(a);
end.

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

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

В языке программирования Pascal, чтобы передавать в процедуру или функцию не данные, а только ссылку на них, перед объявлением формального параметра добавляют ключевое слово var. Тогда наша процедура заполнения массива все-таки будет иметь параметр, и таким образом мы сможем передавать в нее любой массив соответствующего типа:

const
    N = 10;
type
    myArray = array[1..N] of Integer; 
var
    a, e: myArray;

procedure randA(var r: myArray);  
var i: byte;
begin
    for i:=1 to N do
        r[i] := random(100) - 50;
end;

...

begin
    randomize;
    randA(a);
    randA(e);
    writeA(a);
    writeA(e);
end.

В данном случае когда, например, вызывается процедура randA с фактическим параметром a, то с массивом, содержащимся в этой переменной, связывается также имя r — формальный параметр процедуры. Изменение массива через r скажутся на значении a, потому что это два имени одних и тех же данных.

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

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

const
    N = 10;
type
    inArr = array[1..N] of integer; 
    mA = array[1..N] of shortInt;
var
    a: inArr;
    b: mA;
    i: byte;

function mask(var origin: inArr): mA;  
begin
    for i:=1 to N do
        if origin[i] > 0 then
            mask[i] := 1
        else if origin[i] < 0 then
            mask[i] := -1
        else
            mask[i] := 0;
end;

begin
    for i:=1 to N do
        read(a[i]);

    b := mask(a);

    for i:=1 to N do
        write(b[i], ' ');
    writeln;
end.
4 5 -2 -4 0 5 -4 3 2 -1
1 1 -1 -1 0 1 -1 1 1 -1

Как в программе выше функцию превратить в процедуру, чтобы она делала то же самое?

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

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

Напишите программу, в которой функция принимает минимально и максимально возможные значения массива, заполняет массив случайными числами в указанном диапазоне и возвращает этот массив в главный раздел begin-end.