Обработка одномерных массивов целых чисел на языках Си, Паскаль и Python

Информатика 9 класс · тест: 5 вопросов

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

Урок разобран сразу для трёх языков. Над каждым примером кода есть вкладки: выбери свой язык, и сайт запомнит выбор.

Что такое массив

Представь, что нужно сохранить результаты ста игроков. Сто переменных score1, score2, … — неудобно. Вместо них заводят одну переменную-массив.

Массив — набор элементов одного типа, у которого есть общее имя. У каждого элемента есть номер — индекс. Чтобы обратиться к элементу, пишут имя массива и индекс в квадратных скобках: A[3].

Массив с одним индексом — одномерный, как строка таблицы. С двумя индексами — двумерный, как вся таблица. В этом уроке — одномерные массивы целых чисел.

Описание массива и индексы

int A[8] = {-15, -20, -12, -4, -2, 0, 0, 1};
// индексы от 0 до 7
const
  A: array[1..8] of integer = (-15, -20, -12, -4, -2, 0, 0, 1);
  { индексы от 1 до 8 }
A = [-15, -20, -12, -4, -2, 0, 0, 1]
# индексы от 0 до 7

Главное отличие языков — с какого номера начинаются индексы:

Элемент1-й2-й3-й…8-й
Значение−15−20−12…1
Индекс в Си и Python012…7
Индекс в Паскале123…8

В Си и Python нумерация всегда с нуля, поэтому последний элемент массива из N элементов — A[N-1]. В Паскале границы индексов задают при описании; в школьных программах обычно array[1..N], и тогда последний элемент — A[N].

  • Си — размер массива указывают при описании, изменить его потом нельзя. Обращение за пределы массива Си не проверяет — программа прочитает «чужую» память, это частая и опасная ошибка.
  • Паскаль — тип массива пишется как array[начало..конец] of тип.
  • Python — вместо массива используется список. Его длину даёт функция len(A). [0] * N создаёт список из N нулей.

Индекс может быть выражением или даже значением другого элемента. Для массива выше в Python и Си: при i = 1 элемент A[4*i-2] — это A[2], то есть −12; A[A[6]] — это A[0], то есть −15.

Заполнение и вывод

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

Ввод с клавиатуры

for (i = 0; i < N; i++) {
    printf("A[%d]=", i);
    scanf("%d", &A[i]);
}
for i := 1 to N do
begin
  write('A[', i, ']=');
  readln(A[i]);
end;
for i in range(N):
    A[i] = int(input(f"A[{i}]="))

По формуле

for (i = 0; i < N; i++)
    A[i] = 2 * i;       // 0, 2, 4, 6, …
for i := 1 to N do
  A[i] := 2 * i;        { 2, 4, 6, 8, … }
for i in range(N):
    A[i] = 2 * i        # 0, 2, 4, 6, …

Одна и та же формула даёт разные числа: в Паскале индексы начинаются с 1, поэтому первый элемент — 2, а не 0.

Случайные числа и вывод в строку

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

#include <stdio.h>
#include <stdlib.h>   // rand, srand
#include <time.h>     // time

#define N 10

int main(void) {
    int A[N], i;
    srand(time(NULL));             // разные числа при каждом запуске
    for (i = 0; i < N; i++)
        A[i] = rand() % 101 + 10;  // от 10 до 110
    for (i = 0; i < N; i++)
        printf("%d ", A[i]);
    printf("\n");
    return 0;
}
program RandomArray;
const
  N = 10;
var
  A: array[1..N] of integer;
  i: integer;
begin
  randomize;                       { разные числа при каждом запуске }
  for i := 1 to N do
    A[i] := random(101) + 10;      { от 10 до 110 }
  for i := 1 to N do
    write(A[i], ' ');
  writeln;
end.
from random import randint

N = 10
A = [0] * N
for i in range(N):
    A[i] = randint(10, 110)        # от 10 до 110
for i in range(N):
    print(A[i], end=" ")
print()

Как получается отрезок от 10 до 110: в Си rand() % 101 даёт число от 0 до 100, в Паскале random(101) — тоже от 0 до 100; прибавляем 10. В Python randint(10, 110) сразу включает оба конца. В Python весь список можно вывести и одной командой print(A) — в квадратных скобках через запятую.

Сумма элементов

В посёлке N домов, в массиве A — число жителей каждого дома. Сколько всего жителей? Сумму копят так же, как для простых переменных: начинаем с нуля и по очереди прибавляем каждый элемент.

#include <stdio.h>

int main(void) {
    int A[5] = {100, 120, 130, 80, 70};
    int i, s = 0;
    for (i = 0; i < 5; i++)
        s = s + A[i];
    printf("Жителей: %d\n", s);
    return 0;
}
program Residents;
const
  A: array[1..5] of integer = (100, 120, 130, 80, 70);
var
  i, s: integer;
begin
  s := 0;
  for i := 1 to 5 do
    s := s + A[i];
  writeln('Жителей: ', s);
end.
A = [100, 120, 130, 80, 70]
s = 0
for i in range(len(A)):
    s = s + A[i]
print("Жителей:", s)

Ответ — 500. Среднее значение — сумма, делённая на количество элементов: 500 / 5 = 100 жителей на дом. В Python сумму списка даёт и готовая функция sum(A).

Наибольший элемент

Берём первый элемент как «рекорд» и сравниваем с ним все остальные. Нашли больше — это новый рекорд.

int A[6] = {45, 23, 77, 12, 99, 30};
int i, m = A[0];
for (i = 1; i < 6; i++)
    if (A[i] > m)
        m = A[i];
printf("Наибольший: %d\n", m);
m := A[1];
for i := 2 to 6 do
  if A[i] > m then
    m := A[i];
writeln('Наибольший: ', m);
A = [45, 23, 77, 12, 99, 30]
m = A[0]
for i in range(1, len(A)):
    if A[i] > m:
        m = A[i]
print("Наибольший:", m)

Ответ — 99. Наименьший ищут так же, только со знаком <.

Поиск элемента

Есть ли в массиве число x, и если есть — под каким индексом? Запоминаем индекс первого совпадения. Если совпадений нет, в переменной останется значение, которого не бывает у индексов: −1 в Си и Python, 0 в Паскале (у него индексы с 1).

nx = -1;
for (i = 0; i < N; i++)
    if (A[i] == x) {
        nx = i;
        break;          // нашли — дальше не ищем
    }
if (nx >= 0)
    printf("A[%d] = %d\n", nx, x);
else
    printf("Нет такого числа\n");
nx := 0;
for i := 1 to N do
  if A[i] = x then
  begin
    nx := i;
    break;              { нашли — дальше не ищем }
  end;
if nx > 0 then
  writeln('A[', nx, '] = ', x)
else
  writeln('Нет такого числа');
nx = -1
for i in range(N):
    if A[i] == x:
        nx = i
        break           # нашли — дальше не ищем
if nx >= 0:
    print(f"A[{nx}] = {x}")
else:
    print("Нет такого числа")

Подсчёт и сумма по условию

Сколько в массиве чётных чисел? И какова сумма чисел, которые оканчиваются на 4? Это тот же перебор, только внутри цикла — ветвление.

k = 0;
s = 0;
for (i = 0; i < N; i++) {
    if (A[i] % 2 == 0)
        k = k + 1;          // чётное — считаем
    if (A[i] % 10 == 4)
        s = s + A[i];       // оканчивается на 4 — прибавляем
}
printf("Чётных: %d, сумма оканчивающихся на 4: %d\n", k, s);
k := 0;
s := 0;
for i := 1 to N do
begin
  if A[i] mod 2 = 0 then
    k := k + 1;             { чётное — считаем }
  if A[i] mod 10 = 4 then
    s := s + A[i];          { оканчивается на 4 — прибавляем }
end;
writeln('Чётных: ', k, ', сумма оканчивающихся на 4: ', s);
k = 0
s = 0
for i in range(N):
    if A[i] % 2 == 0:
        k = k + 1           # чётное — считаем
    if A[i] % 10 == 4:
        s = s + A[i]        # оканчивается на 4 — прибавляем
print("Чётных:", k, "сумма оканчивающихся на 4:", s)

Для массива 14, 7, 24, 9, 30: чётных — три (14, 24, 30), сумма оканчивающихся на 4 — 14 + 24 = 38. Для положительных чисел это верно во всех трёх языках; у отрицательных остаток в Си и Паскале получается со знаком минус, поэтому -14 % 10 там равно −4, а не 4.

Синтаксис коротко

СиПаскальPython
описать массив из 10 целыхint A[10];A: array[1..10] of integer;A = [0] * 10
индексыот 0 до 9от 1 до 10от 0 до 9
перебор всех элементовfor (i = 0; i < 10; i++)for i := 1 to 10 dofor i in range(10):
длиназадаётся при описаниизадаётся при описанииlen(A)
случайное от 10 до 110rand() % 101 + 10random(101) + 10randint(10, 110)

🎯 Самое главное

  • Массив — набор однотипных элементов под общим именем; к элементу обращаются по индексу: A[i].
  • В Си и Python индексы с 0, в Паскале — те, что указаны при описании, обычно с 1.
  • Заполняют массив вводом, формулой или случайными числами — циклом по всем индексам.
  • Сумма, наибольший элемент, поиск, подсчёт по условию — перебор элементов в цикле.

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

1. Массив из 20 элементов. Какой индекс у последнего элемента в Си? В Паскале с описанием array[1..20]?

В Си — 19, в Паскале — 20.

2. Какие значения получит массив из 5 элементов после цикла A[i] = 2 * i в Python? А в Паскале с индексами от 1?

Python: 0, 2, 4, 6, 8. Паскаль: 2, 4, 6, 8, 10.

3. Почему при поиске «нет такого числа» отмечают индексом −1 (или 0 в Паскале)?

У настоящего элемента такого индекса не бывает, поэтому по нему сразу видно, что совпадение не найдено.

4. Что будет в Си, если обратиться к A[10] у массива int A[10]?

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

Проверь себя

5 случайных вопросов по этому уроку — при следующем открытии будут другие. Ответы проверяются сразу, без регистрации.