Что значит array в Паскале: объявление массива, индексы и типичные ошибки

Что значит array в Паскале: объявление массива, индексы и типичные ошибки Полезное

array в Паскале — это зарезервированное слово, которым описывают тип «массив»: набор элементов одного типа под общим именем, где каждый элемент доступен по индексу. Запись a: array[1..5] of integer читается так: «a — массив из пяти целых чисел с индексами от 1 до 5».

Этим же словом описывают три разные вещи, и их стоит сразу развести:

  • статический массив — array[1..5] of integer: диапазон индексов задан в объявлении, размер не меняется;
  • динамический массив — array of integer в разделе var: размер задается при выполнении процедурой SetLength;
  • открытый массив — array of integer в списке параметров подпрограммы (Free Pascal, Delphi): способ принять массив любой длины. В PascalABC.NET такая запись означает динамический массив.

Все примеры проверены 30.09.2026 в Free Pascal 3.2.2 (Linux, 64-битный ARM). Там, где другие диалекты ведут себя иначе, это сказано отдельно.

Минимальный пример с array

Программа заполняет массив квадратами чисел от 1 до 5, выводит элементы и считает их сумму.

program ArrayDemo;
var
  a: array[1..5] of integer;
  i, sum: integer;
begin
  for i := 1 to 5 do
    a[i] := i * i;

  sum := 0;
  for i := 1 to 5 do
  begin
    write(a[i], ' ');
    sum := sum + a[i];
  end;
  writeln;
  writeln('Сумма: ', sum);
end.

В консоли появятся две строки:

1 4 9 16 25 
Сумма: 55

Массив объявлен в разделе var, как обычная переменная. К элементу обращаются по имени и индексу в квадратных скобках: a[3] — третий элемент, в нем лежит 9.

Как читать запись array[1..5] of integer

Часть записи Что означает
a имя переменной-массива
array зарезервированное слово: «это массив»
[1..5] диапазон индексов: первый и последний, через две точки
of integer тип каждого элемента

Число элементов получается из диапазона: для [1..5] это 5 — 1 + 1 = 5. Границы статического массива — константы, известные до запуска программы. Подставить туда переменную нельзя, зато можно именованную константу: const N = 5; и затем array[1..N] of integer.

Две частые ошибки записи. Между границами ставят ровно две точки, а не три. И в скобках указывают диапазон, а не количество: на строку a: array[5] of integer; компилятор отвечает отказом.

err_decl.pas(3,13) Error: Error in type definition

Диапазон индексов: не только с единицы

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

program Ranges;
type
  TDay = (Mon, Tue, Wed, Thu, Fri, Sat, Sun);
var
  temp: array[-3..3] of real;
  count: array['a'..'z'] of integer;
  hours: array[TDay] of integer;
  s: string;
  c: char;
  i: integer;
begin
  writeln(Low(temp), ' ', High(temp), ' ', Length(temp));

  for c := 'a' to 'z' do
    count[c] := 0;
  s := 'abracadabra';
  for i := 1 to Length(s) do
    count[s[i]] := count[s[i]] + 1;
  writeln('a: ', count['a'], ', b: ', count['b']);

  hours[Sat] := 4;
  writeln(Length(hours), ' ', hours[Sat]);
end.
-3 3 7
a: 5, b: 2
7 4

Функции Low, High и Length возвращают нижнюю границу, верхнюю границу и число элементов. Массив count с индексами-буквами сразу дает счетчик букв: в слове «abracadabra» буква a встретилась 5 раз, b — 2 раза. Пример рассчитан на строку из строчных латинских букв: другой символ вышел бы за диапазон 'a'..'z'.

Статический и динамический массив: SetLength

Если размер становится известен только при выполнении, объявляют динамический массив: без диапазона, с установкой длины через SetLength.

program DynDemo;
var
  a, b: array of integer;
  s, t: array[1..3] of integer;
  n, i: integer;
begin
  n := 4;                 { размер известен только при выполнении }
  SetLength(a, n);
  writeln(Low(a), ' ', High(a), ' ', Length(a));

  for i := 0 to High(a) do
    a[i] := (i + 1) * 10;
  SetLength(a, 6);        { старые значения сохранились, новые - нули }
  for i := 0 to High(a) do
    write(a[i], ' ');
  writeln;

  b := a;                 { динамический: копируется ссылка }
  b[0] := 99;
  writeln(a[0]);

  b := Copy(a);           { настоящая копия }
  b[0] := 1;
  writeln(a[0]);

  s[1] := 1;
  t := s;                 { статический: копируются все элементы }
  t[1] := 99;
  writeln(s[1]);
end.
0 3 4
10 20 30 40 0 0 
99
99
1

Первая строка вывода показывает главное отличие: индексы динамического массива всегда начинаются с нуля, последний индекс равен Length(a) - 1. Третья и четвертая строки — про присваивание: b := a не копирует элементы, обе переменные указывают на одни и те же данные, поэтому запись в b[0] изменила a[0]. Независимую копию дает Copy.

Свойство Статический array[1..5] of T Динамический array of T
Размер задан в объявлении константами задается SetLength при выполнении
Нижний индекс любой, какой указан всегда 0
Изменение размера невозможно повторный SetLength
Присваивание b := a копирует элементы копирует ссылку, нужна Copy
Начальные значения не гарантированы, заполняйте сами после SetLength — нули

По какому признаку выбирать: если число элементов фиксировано условием задачи (12 месяцев, 7 дней, 26 букв), берите статический массив. Если размер вводит пользователь или он зависит от данных, берите динамический.

Динамические массивы есть в Free Pascal, Delphi и PascalABC.NET. В Turbo Pascal 7 их нет: там для тех же задач объявляют статический массив «с запасом» и отдельно хранят число занятых элементов.

Открытый массив: array of в параметрах

В заголовке подпрограммы запись array of integer означает не динамический массив, а открытый массив-параметр. Такая функция принимает массив любой длины и любого вида.

program OpenArr;

function Sum(const a: array of integer): integer;
var
  i: integer;
begin
  Sum := 0;
  for i := 0 to High(a) do
    Sum := Sum + a[i];
end;

procedure ShowBounds(const a: array of integer);
begin
  writeln(Low(a), '..', High(a));
end;

var
  s: array[1..3] of integer = (10, 20, 30);
  d: array of integer;
begin
  SetLength(d, 2);
  d[0] := 5;
  d[1] := 7;

  writeln(Sum(s));
  writeln(Sum(d));
  writeln(Sum([1, 2, 3, 4]));
  ShowBounds(s);
end.
60
12
10
0..2

Одна и та же Sum сложила статический массив, динамический и список значений в квадратных скобках. Последняя строка вывода — ловушка: снаружи массив s имеет индексы 1..3, а внутри подпрограммы открытый массив всегда нумеруется с нуля, то есть 0..2. Поэтому цикл внутри пишут от 0 до High(a), а не от 1 до длины.

Менять длину открытого массива через SetLength внутри подпрограммы нельзя: это другой тип, хотя запись совпадает.

Так устроены Free Pascal и Delphi. В PascalABC.NET открытых массивов нет: там array of integer в параметрах — обычный динамический массив, и статический массив array[1..3] of integer в такую подпрограмму не передать.

Типичная ошибка: выход за границы массива

Самая частая ошибка с array — обращение к индексу, которого нет. Ниже цикл идет до 6 при массиве на пять элементов.

program ErrLoop;
var
  a: array[1..5] of integer;
  guard: integer;
  i: integer;
begin
  guard := 777;
  for i := 1 to 6 do
    a[i] := 0;
  writeln('guard = ', guard);
end.

Программа компилируется и завершается без сообщений, но печатает не 777:

guard = 0

Запись в несуществующий a[6] попала в соседнюю переменную. Это результат конкретного прогона: что именно окажется испорчено, зависит от компилятора и платформы, и на другой машине та же программа может случайно напечатать 777. Ошибка при этом никуда не девается, она просто не видна.

Чтобы выход за границы обнаруживался, включают проверку диапазонов директивой {$R+} в первой строке файла (или ключом компилятора -Cr). Та же программа с {$R+} останавливается на шестом шаге цикла:

Runtime error 201 at $0000000000400168

Код 201 в Free Pascal — это ошибка проверки диапазона; адрес после at на другой машине будет другим. Проверка работает и для динамических массивов: цикл for i := 1 to 3 по массиву из трех элементов (индексы 0..2) завершается с тем же кодом 201.

Исправление — не писать границы числами, а брать их у самого массива:

{$R+}
program Fix;
var
  a: array[1..5] of integer;
  i: integer;
begin
  for i := Low(a) to High(a) do
    a[i] := 0;
  writeln('Обнулено элементов: ', Length(a));
end.
Обнулено элементов: 5

Цикл от Low(a) до High(a) остается верным для статического, динамического и открытого массива, в том числе если диапазон в объявлении потом изменят. На время обучения и отладки {$R+} стоит держать включенной: проверка немного замедляет программу, зато ошибка проявляется сразу и в том месте, где допущена.

Если индекс за границей записан константой, например a[6] := 1, Free Pascal замечает это уже при компиляции. В нашем прогоне без {$R+} это было предупреждение, а не отказ:

err_const.pas(5,5) Warning: range check error while evaluating constants (6 must be between 1 and 5)

С {$R+} то же сообщение становится ошибкой (Error: range check error while evaluating constants), и программа не компилируется.

Выводы

  • array — зарезервированное слово Паскаля для описания массива: array[диапазон] of тип.
  • Диапазон индексов задают двумя точками; индексом может быть любой порядковый тип, начинать с единицы не обязательно.
  • Статический массив имеет фиксированный размер, динамический (array of T плюс SetLength) — изменяемый и всегда нумеруется с нуля.
  • В Free Pascal и Delphi array of T в параметрах подпрограммы — открытый массив: принимает массив любой длины, внутри индексы идут от 0 до High(a). В PascalABC.NET та же запись означает динамический массив.
  • От выхода за границы защищают цикл от Low(a) до High(a) и проверка диапазонов {$R+}.

Где применяется / связь с практикой

Освойте тему на практике

Массив — базовая структура данных: на нем строят поиск, сортировки, стек, очередь, кучу и хеш-таблицу. Понимание того, как устроены индексы и чем грозит выход за границы, переносится на любой язык. Системно эти темы разбирают на курсе «Алгоритмы и структуры данных». Познакомиться с форматом занятий можно на открытых уроках Otus.

Смежные темы: одномерные массивы в языке Pascal, алгоритмы в Pascal.

FAQ

Как объявить двумерный массив?
Через запятую указывают два диапазона: m: array[1..3, 1..4] of integer. К элементу обращаются по двум индексам: m[2, 3].

Обнуляются ли элементы массива после объявления?
Для статического массива на это рассчитывать нельзя: заполняйте его сами перед чтением. В динамическом массиве элементы, добавленные через SetLength, равны нулю.

Можно ли вернуть массив из функции как array[1..5] of integer?
Напрямую в заголовке так писать нельзя. Сначала описывают именованный тип в разделе type, например TVec = array[1..5] of integer, и указывают в заголовке его имя.

OTUS Журнал
Скидка 5% 12-19 октября на курсы (popup)
Бесплатные открытые уроки (поп-ап)