Обработка одномерных массивов целых чисел на языках Си, Паскаль и Python
Плейлист из тысячи треков, список друзей, таблица рекордов — везде одна и та же идея: много однотипных значений под одним именем. В программировании это массив.
Урок разобран сразу для трёх языков. Над каждым примером кода есть вкладки: выбери свой язык, и сайт запомнит выбор.
Что такое массив
Представь, что нужно сохранить результаты ста игроков. Сто переменных 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 |
| Индекс в Си и Python | 0 | 1 | 2 | … | 7 |
| Индекс в Паскале | 1 | 2 | 3 | … | 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 do | for i in range(10): |
| длина | задаётся при описании | задаётся при описании | len(A) |
| случайное от 10 до 110 | rand() % 101 + 10 | random(101) + 10 | randint(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 случайных вопросов по этому уроку — при следующем открытии будут другие. Ответы проверяются сразу, без регистрации.