Одномерный массив в Pascal — это набор из фиксированного числа элементов одного типа под общим именем, где к каждому элементу обращаются по одному индексу: a[3] — третий элемент массива a, если индексы начинаются с 1. Границы индекса задает программист при объявлении, например array[1..10] of integer.
Содержание
Ниже — объявление, заполнение, вывод, сумма и максимум, поиск, сортировка пузырьком, передача в процедуру и защита от выхода за границы. Программы проверены в Free Pascal 3.2.2, вывод фактический.
Три понятия, которые путают
| Термин | Что это | Пример |
|---|---|---|
| Индекс | Номер ячейки, по которому обращаются к элементу | i в a[i] |
| Значение элемента | То, что лежит в ячейке | a[i] = 25 |
| Диапазон индексов | Допустимые номера, задаются при объявлении | 1..8, 0..9, -5..5 |
Нижняя граница не обязана быть единицей: array[0..9] и array[-5..5] тоже корректны, а индексом может быть и char или перечисление. В учебных задачах чаще берут 1..N.
Минимальная рабочая программа
Сначала целиком: объявляем массив из 8 элементов, заполняем квадратами чисел, выводим, считаем сумму и ищем максимум вместе с его позицией.
program ArrayBasics;
const
N = 8;
var
a: array[1..N] of integer;
i, sum, maxVal, maxPos: integer;
begin
{ заполнение по формуле: квадраты чисел 1..N }
for i := 1 to N do
a[i] := i * i;
{ вывод в одну строку }
for i := 1 to N do
write(a[i], ' ');
writeln;
{ сумма и максимум с его индексом }
sum := 0;
maxVal := a[1];
maxPos := 1;
for i := 1 to N do
begin
sum := sum + a[i];
if a[i] > maxVal then
begin
maxVal := a[i];
maxPos := i;
end;
end;
writeln('Сумма: ', sum);
writeln('Максимум: ', maxVal, ' на позиции ', maxPos);
end.
Вывод:
1 4 9 16 25 36 49 64
Сумма: 204
Максимум: 64 на позиции 8
Что здесь важно:
- Размер вынесен в константу
N. Если понадобится 100 элементов, меняется одна строка, а не все циклы. - Массив целиком на экран не выводится:
writeln(a)для статического массива не скомпилируется, нужен цикл по индексам. - Максимум начинают с
a[1], а не с нуля. Иначе на массиве из одних отрицательных чисел программа вернет 0, которого в массиве нет. - Сумму обнуляют перед циклом: в Free Pascal локальные переменные процедур не инициализируются, и надеяться на ноль нельзя.
Способы заполнить массив
По формуле — как в примере выше: a[i] := i * i. Подходит, когда значение зависит от номера.
Случайными числами — удобно для проверки программы на больших данных:
Randomize; { новая последовательность при каждом запуске }
for i := 1 to N do
a[i] := Random(100) + 1; { Random(100) дает 0..99, значит a[i] в 1..100 }
Вывод разный от запуска к запуску. Без Randomize последовательность повторяется — так удобнее отлаживать.
С клавиатуры — когда количество элементов заранее неизвестно, объявляют массив с запасом и хранят фактическую длину в отдельной переменной:
program ReadArr;
const
NMAX = 100;
var
a: array[1..NMAX] of integer;
n, i: integer;
begin
write('Сколько чисел (1..', NMAX, ')? ');
readln(n);
if (n < 1) or (n > NMAX) then
begin
writeln('Нужно число от 1 до ', NMAX);
halt(1);
end;
for i := 1 to n do
read(a[i]);
for i := n downto 1 do
write(a[i], ' ');
writeln;
end.
При вводе 4, затем 10 20 30 40 программа печатает числа в обратном порядке: 40 30 20 10. Проверка n перед циклом обязательна: без нее ввод 150 приведет к записи за пределы массива.
Еще один вариант — инициализация при объявлении. В Free Pascal и Delphi это выглядит так: a: array[1..8] of integer = (5, 3, 8, 1, 9, 2, 7, 4);. В других средах синтаксис может отличаться.
Линейный поиск элемента
Задача: найти, на какой позиции стоит число x, или сообщить, что его нет. Проходим массив слева направо и останавливаемся на первом совпадении.
program LinearSearch;
const
N = 8;
a: array[1..N] of integer = (5, 3, 8, 1, 9, 2, 7, 4);
var
i, x, pos: integer;
begin
x := 9;
pos := 0; { 0 = не найдено: вне диапазона 1..N }
i := 1;
while (i <= N) and (pos = 0) do
begin
if a[i] = x then
pos := i;
i := i + 1;
end;
if pos > 0 then
writeln('Число ', x, ' найдено на позиции ', pos)
else
writeln('Числа ', x, ' в массиве нет');
end.
Вывод: Число 9 найдено на позиции 5. Здесь использован while, а не for, потому что цикл должен закончиться сразу после находки. Значение 0 для «не найдено» работает только потому, что индексы начинаются с 1; при диапазоне 0..9 нужен другой признак, например отдельная переменная found: boolean.
Сортировка пузырьком: сначала руками
Пузырьковая сортировка сравнивает соседние элементы и меняет их местами, если левый больше правого. За один проход самый большой из неотсортированных элементов «всплывает» в конец. Вот массив 5 3 8 1 9 2 7 4 после каждого прохода:
| Проход | Состояние массива | Были обмены |
|---|---|---|
| 1 | 3 5 1 8 2 7 4 9 | да |
| 2 | 3 1 5 2 7 4 8 9 | да |
| 3 | 1 3 2 5 4 7 8 9 | да |
| 4 | 1 2 3 4 5 7 8 9 | да |
| 5 | 1 2 3 4 5 7 8 9 | нет — стоп |
На пятом проходе обменов не было, значит массив уже упорядочен, и оставшиеся проходы можно не делать. Теперь то же в коде:
program BubbleSort;
const
N = 8;
var
a: array[1..N] of integer = (5, 3, 8, 1, 9, 2, 7, 4);
i, j, tmp: integer;
swapped: boolean;
begin
for i := 1 to N - 1 do
begin
swapped := false;
for j := 1 to N - i do
if a[j] > a[j + 1] then
begin
tmp := a[j];
a[j] := a[j + 1];
a[j + 1] := tmp;
swapped := true;
end;
if not swapped then
break;
end;
for i := 1 to N do
write(a[i], ' ');
writeln;
end.
Вывод: 1 2 3 4 5 7 8 9. Внутренний цикл идет до N - i, а не до N: во-первых, хвост уже отсортирован, во-вторых, при j = N обращение a[j + 1] вышло бы за границу массива. Пузырек нагляден, но медленный (порядка N² сравнений); на больших данных берут быструю сортировку или слиянием.
Выход за границы массива и {$R+}
Самая частая ошибка с массивами — обращение к индексу вне диапазона. Неверный код: цикл до 6 при массиве из 5 элементов.
program OutOfRangeNoCheck;
var
a: array[1..5] of integer;
i: integer;
begin
for i := 1 to 6 do
a[i] := i * 10;
writeln('Готово');
end.
Результат в Free Pascal с настройками по умолчанию: программа печатает Готово без ошибок. Но значение 60 записано в память за пределами массива и может испортить соседние переменные; поведение непредсказуемо.
Исправление для отладки — включить проверку диапазонов директивой {$R+} в начале программы (или ключом компилятора -Cr):
program OutOfRange;
{$R+}
var
a: array[1..5] of integer;
i: integer;
begin
for i := 1 to 6 do
a[i] := i * 10;
writeln('Готово');
end.
Теперь программа останавливается на ошибочной записи:
Runtime error 201 at $0000000000400168
Код 201 в Free Pascal — ошибка проверки диапазона, адрес зависит от платформы; с модулем SysUtils будет исключение ERangeError. Проверка замедляет программу, ее включают на время разработки. Само исправление — граница цикла: надежнее всего for i := Low(a) to High(a).
Массив как параметр процедуры
Массив нельзя передать, описав его тип прямо в заголовке (procedure P(a: array[1..5] of integer) не скомпилируется). Сначала объявляют именованный тип:
program ArrayParam;
const
N = 5;
type
TArr = array[1..N] of integer;
function Sum(const arr: TArr): integer;
var
i, s: integer;
begin
s := 0;
for i := 1 to N do
s := s + arr[i];
Sum := s;
end;
procedure FillSquares(var arr: TArr);
var
i: integer;
begin
for i := 1 to N do
arr[i] := i * i;
end;
var
a: TArr;
begin
FillSquares(a);
writeln('Сумма квадратов 1..', N, ': ', Sum(a));
end.
Вывод: Сумма квадратов 1..5: 55. var — процедура меняет исходный массив; const — только чтение; без модификатора передается копия, изменения не видны снаружи.
Статический и динамический массив
Все примеры выше — статические массивы: размер известен при компиляции и не меняется. В Free Pascal и Delphi есть и динамические массивы, размер которых задается во время работы:
program DynArr;
var
d: array of integer;
i: integer;
begin
SetLength(d, 4);
for i := 0 to High(d) do
d[i] := i + 1;
writeln('Low=', Low(d), ' High=', High(d), ' Length=', Length(d));
for i := Low(d) to High(d) do
write(d[i], ' ');
writeln;
end.
Вывод:
Low=0 High=3 Length=4
1 2 3 4
| Статический | Динамический | |
|---|---|---|
| Объявление | array[1..N] of integer |
array of integer + SetLength |
| Размер | Фиксирован при компиляции | Задается и меняется при работе |
| Индексы | Любой диапазон, например 1..N | Всегда с 0 до Length - 1 |
| Где есть | Любой Pascal | Free Pascal, Delphi, PascalABC.NET; в стандартном Pascal нет |
Ловушка: цикл for i := 1 to Length(d) пропустит первый элемент и выйдет за последний. for i := Low(d) to High(d) работает для обоих видов.
Выводы
- Одномерный массив — фиксированный набор однотипных элементов с одним индексом; диапазон индексов задается при объявлении и не обязан начинаться с 1.
- Размер выносите в константу, а циклы пишите через
Low/High, чтобы не ошибиться с границами. - Максимум и минимум начинают с первого элемента, а не с нуля; поиск с остановкой удобнее писать через
while. - Выход за границы в Free Pascal по умолчанию не ловится; на время отладки включайте
{$R+}. - Динамические массивы индексируются с нуля — это главное отличие от привычных статических
1..N.
Где применяется / связь с практикой
Освойте тему на практике
Массив — основа учебных алгоритмов: поиск, сортировки, префиксные суммы, бинарный поиск. Задачи на массивы часто дают на собеседованиях, а навык работы с индексами переносится на любой язык. Если хочется разобрать алгоритмы и структуры данных системно, с оценкой сложности и практикой, посмотрите курс «Алгоритмы и структуры данных». Для знакомства с темой подойдут бесплатные открытые уроки Otus.
FAQ
Можно ли в Pascal объявить массив с индексами от 0?
Да, array[0..9] of integer — обычное объявление на 10 элементов. Важно, чтобы циклы использовали те же границы, поэтому удобнее писать Low(a) и High(a).
Можно ли присвоить один массив другому целиком?
Да, если оба объявлены одним именованным типом (например, TArr): b := a копирует все элементы. Сравнивать массивы через = так же нельзя — сравнение пишут циклом.



