Глиф Учебники

Урок 6. Массивы

Курс «Pascal» · урок 6 из 9 · 4 минуты чтения

Пять оценок можно хранить в пяти переменных, но тридцать уже неудобно, а сто — невозможно. Для этого есть массив — ряд пронумерованных ячеек одного типа под одним именем.

Описание массива

Pascal
var
  a: array[1..10] of integer;

Это десять целых чисел: a[1], a[2], …, a[10]. Число в квадратных скобках — индекс, номер элемента. Диапазон 1..10 задают при описании, и во время работы программы он не меняется. Индексом может быть переменная или выражение: a[i], a[i + 1].

Размер удобно задать константой — тогда его легко поменять в одном месте:

Pascal
const
  MaxN = 100;
var
  a: array[1..MaxN] of integer;

Помните, что Pascal не различает большие и маленькие буквы: константу N и переменную n в одной программе описать нельзя. Поэтому константа здесь названа MaxN.

Ввод, сумма и среднее

Обычно в задаче сначала вводят количество чисел, а потом сами числа. Массив описывают с запасом, а используют первые n элементов:

Pascal
program ArraySum;
const
  MaxN = 100;
var
  a: array[1..MaxN] of integer;
  n, i: integer;
  s: longint;
begin
  readln(n);
  for i := 1 to n do
    read(a[i]);
  s := 0;
  for i := 1 to n do
    s := s + a[i];
  writeln('Сумма: ', s);
  writeln('Среднее: ', (s / n):0:2);
end.
Ввод
5
4 8 15 16 23
Вывод
Сумма: 66
Среднее: 13.20
индекс a 1 4 2 8 3 15 4 16 5 23 6 7 … 100 заполнены первые n = 5 запас до MaxN = 100
Массив a описан на 100 элементов с запасом, а заполнены только первые n = 5: под номерами от 1 до 5 лежат 4, 8, 15, 16 и 23.

read(a[i]) в цикле читает числа по одному, поэтому их можно набрать в одну строку через пробел или каждое с новой строки. Среднее делится через / и выводится с форматом — оно дробное.

Вывод массива

Элементы выводят циклом. Через пробел в одну строку:

Pascal
for i := 1 to n do
  write(a[i], ' ');
writeln;

В обратном порядке — тот же цикл с downto: for i := n downto 1 do.

Максимум и его номер

Начальное значение максимума берут из первого элемента, а не ноль: если все числа отрицательные, ноль окажется больше любого из них.

Pascal
program ArrayMax;
var
  a: array[1..100] of integer;
  n, i, maxI: integer;
begin
  readln(n);
  for i := 1 to n do
    read(a[i]);
  maxI := 1;
  for i := 2 to n do
    if a[i] > a[maxI] then
      maxI := i;
  writeln('Максимум: ', a[maxI], ', номер: ', maxI);
end.
Ввод
6
3 -7 12 5 12 0
Вывод
Максимум: 12, номер: 3

Программа запоминает номер наибольшего элемента. Знак > оставляет первый из одинаковых максимумов; с >= был бы последний, номер 5. Больше вариантов — в справке Как найти максимум и минимум в массиве.

i a[i] a[i] > a[maxI] maxI 1 3 начало 1 2 −7 −7 > 3 нет 1 3 12 12 > 3 да 3 4 5 5 > 12 нет 3 5 12 12 > 12 нет 3 6 0 0 > 12 нет 3
Поиск максимума по шагам: maxI начинается с 1, при i = 3 число 12 больше 3 и maxI становится 3, а второе 12 при i = 5 не больше первого, поэтому ответ — номер 3.

Подсчёт и поиск

Сколько элементов подходят под условие — заводят счётчик:

Pascal
program CountEven;
var
  a: array[1..100] of integer;
  n, i, count: integer;
begin
  readln(n);
  for i := 1 to n do
    read(a[i]);
  count := 0;
  for i := 1 to n do
    if a[i] mod 2 = 0 then
      count := count + 1;
  writeln('Чётных: ', count);
end.
Ввод
7
5 8 13 2 0 7 10
Вывод
Чётных: 4

Есть ли в массиве нужное число и где оно — цикл while, который останавливается на первой находке:

Pascal
program Search;
var
  a: array[1..100] of integer;
  n, i, x: integer;
begin
  readln(n);
  for i := 1 to n do
    read(a[i]);
  readln(x);
  i := 1;
  while (i <= n) and (a[i] <> x) do
    i := i + 1;
  if i <= n then
    writeln('Число ', x, ' на месте ', i)
  else
    writeln('Числа ', x, ' нет');
end.
Ввод
5
10 20 30 40 50
40
Вывод
Число 40 на месте 4

В условии (i <= n) and (a[i] <> x) проверка границы стоит первой. Когда i станет больше n, вторая часть уже не проверяется, и программа не заглядывает за конец заполненной части массива.

Случайные числа

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

Pascal
program RandomArray;
var
  a: array[1..10] of integer;
  i: integer;
begin
  randomize;
  for i := 1 to 10 do
  begin
    a[i] := random(100);
    write(a[i], ' ');
  end;
  writeln;
end.

random(100) даёт целое от 0 до 99, randomize один раз в начале делает числа разными при каждом запуске. Поэтому вывод у этой программы каждый раз свой. Подробно — в справке Случайные числа: random и randomize.

Двумерный массив

Таблица из строк и столбцов — массив с двумя индексами: b[строка, столбец]. Обходят его двумя вложенными циклами:

Pascal
program Matrix;
var
  b: array[1..3, 1..4] of integer;
  i, j: integer;
begin
  for i := 1 to 3 do
    for j := 1 to 4 do
      b[i, j] := i * 10 + j;
  for i := 1 to 3 do
  begin
    for j := 1 to 4 do
      write(b[i, j]:4);
    writeln;
  end;
end.
Вывод
  11  12  13  14
  21  22  23  24
  31  32  33  34

Первая цифра каждого числа — номер строки, вторая — номер столбца.

j — номер столбца i — номер строки 1 2 3 4 1 11 12 13 14 2 21 22 23 24 3 31 32 33 34 b[3, 2] = 32
Двумерный массив b — таблица из 3 строк и 4 столбцов: первый индекс выбирает строку, второй — столбец, поэтому элемент в строке 3 и столбце 2 равен 32.

Выход за границы

Если обратиться к a[0] или a[101] у массива array[1..100], PascalABC.NET остановит программу с ошибкой «Индекс выходит за границы массива». Free Pascal по умолчанию границы не проверяет: программа прочитает чужую память и выдаст странный результат или упадёт. Чтобы Free Pascal тоже проверял индексы, компилируйте с ключом -Cr: fpc -Cr prog.pas. Подробно — в справке Ошибки при выполнении программы.

Частые ошибки

Коротко

Проверьте себя

1. Сколько элементов в массиве a: array[1..20] of integer?
2. Почему максимум лучше начинать с a[1], а не с нуля?
3. Что выведет программа?
Pascal
var
  a: array[1..4] of integer;
  i: integer;
begin
  for i := 1 to 4 do
    a[i] := i * i;
  writeln(a[3]);
end.
4. Как обратиться к элементу двумерного массива в строке 2 и столбце 3?