Любая программа состоит из составных частей: переменных, разных типов данных, функций, методов и других вещей. Сегодня мы разберём одну из основных составляющих программ — массив.
Что такое массив
Массив объединяет однотипные элементы программы в наборы — в некоторых языках такие наборы называются коллекциями.
Получается, что массив — это объединение нескольких элементов одного типа. Это могут быть строки, целые числа, двоичные значения.
В разных языках и их разных версиях массивы различаются внешним видом, принципами работы и даже названиями. Например, в Python или JavaScript под массивом чаще всего понимают списки. Вместе с этим списки — это одна из коллекций элементов. Поэтому однозначного строго определения массива нет.
Для лучшего понимания мы разберём несколько вариантов массивов.
Простой пример из жизни
Классический массив можно описать так. Представьте, что у вас есть сумка-холодильник для алюминиевых банок. Она сделана для вещей определённого размера, и у такой сумки есть конечный объём: в неё нельзя положить больше банок, чем предусмотрено.

Обычный массив — это такая же сумка-холодильник. Вы выбираете, какого объёма он будет и что в нём хранить. Как и как сумку-холодильник после покупки, такой массив нельзя изменить после создания — берёшь таким, какой он есть.
Но это только про простые массивы. А ещё есть динамические, двухмерные, многомерные. Про них мы тоже расскажем.
Ключевые термины: элементы, индекс, длина
Главная польза от массива, назовём его хранилищем, появляется при работе с элементами. Значения массивов объединяет их тип. Поэтому можно сказать, что массивом будет не только сумка, но и любой контейнер, в котором хранится один вид вещей: одежда, книги, инструменты, игрушки.
Ещё у каждого элемента есть порядковое число, которое называется индексом. В программировании индексы особенно удобны, потому что сильно влияют на скорость работы.
Длина массива — это его вместимость. Если вы создали массив с длиной 10, в него влезет максимум 10 элементов. Так же в сумку вместимостью 8 банок поместится не больше 8 банок. При этом заполнять массив до максимума необязательно.
Бонус для читателей
Если вам интересно погрузиться в мир ИТ и при этом немного сэкономить, держите наш промокод на курсы Практикума. Он даст вам скидку при оплате, поможет с льготной ипотекой и даст безлимит на маркетплейсах. Ладно, окей, это просто скидка, без остального, но хорошая.
Массив в программировании
Массив в программировании — это тоже контейнер, только цифровой.
В разных технологиях массивы различаются. Для примера представим визуально, как выглядит массив из целых чисел и длиной, равной 6. Тут есть элементы и их индексы:

Длина массива равна 6 — это максимальное количество чисел, которое в него влезет:
Обратите внимание, что номер первого элемента — 0. Так происходит потому, что программа присваивает элементам адреса ячеек памяти, где они хранятся. Адрес каждого элемента считается через смещение от первого элемента. У первого элемента смещения нет, поэтому его индекс равен 0.
Для чего нужны массивы в коде?
Массивы могут дать программе несколько преимуществ. Вот несколько основных.
- В массиве удобно хранить много значений. Когда программист объявляет массив, он придумывает название переменной, и в этой переменной могут храниться сотни элементов. При работе мы используем одну переменную и просим выдать значение по нужному индексу. Это экономит память и упрощает структуру программы.
- Индексы делают работу быстрее. Компьютер сразу понимает, где искать нужный элемент, когда мы запрашиваем его по номеру. Поэтому для получения элемента системе всегда нужно одно действие — в разработке такой показатель называется O(1), то есть постоянное время.
- Массивы можно быстро обрабатывать, потому что у них есть такое свойство, как итерируемость. Это значит, что у разработчика есть возможность перебирать все элементы массива и применять к ним какие-то действия. Например, использовать элементы для других вычислений. Некоторые массивы можно изменять, но это зависит от типа массива и языка программирования.
- Возможность работы с алгоритмами. Алгоритмы — один из основных разделов в программировании. Это набор действий, которые решают определённую задачу оптимальным способом. Они могут упорядочивать, представлять наборы значений удобным способом, переходить на другой уровень задач программы. Для большинства алгоритмов нужны массивы.
Сам по себе массив — ещё не залог хорошей работы приложения или сервиса. Но он даёт возможности, которые опытный разработчик может использовать в правильных местах и сильно поднять производительность и функциональность программы.
Как объявить массив
Принцип объявления массива всегда один: нужно дать ему название и указать, что в нём будет храниться.
Это действие будет выглядеть по-разному для разных языков программирования, поэтому дальше мы посмотрим на несколько вариантов. Обратите внимание, что чаще всего сразу наполнять массив элементами необязательно, но мы заполним, потому что так нагляднее.
Сначала — массив в Python. Обычно под этим словом здесь понимают список, который немного отличается от классического понимания массива: он может содержать элементы любого типа и в любом количестве.
# создаём массив с математическими константами
constants = [3.14159, 2.71828, 299792458, 6.67430e-11]
Такие же массивы используются в JavaScript. Перед объявлением массива нужно поставить тип переменной. У нас это let:
// создаём массив с двоичными значениями
let binary = [0b1010, 0b1111, 0b0101, 0b0011];
В C++ при создании нужно указать размер массива, чтобы система знала, сколько памяти выделить. Но если мы сразу объявляем элементы, программа поймёт размер автоматически, поэтому нужно указать только тип значений.
Так можно объявить массив булевых переменных:
// создаём массив булевых значений
bool flags[] = {true, false, true, true, false};
В массив можно добавить и более сложные элементы. Для примера — вот такой массив в C# с данными формата даты:
// создаём массив с датами (объекты типа DateTime)
DateTime[] dates = {
new DateTime(2024, 1, 1),
new DateTime(2024, 7, 4),
new DateTime(2025, 12, 25)
};
Выглядят массивы по-разному, но суть везде одна: есть набор значений, которые хранятся в переменной и имеют свой отдельный номер-индекс.
Виды массивов: от простого к сложному
Разберём типы массивов и выясним, почему в языках они могут работать и называться по-разному.
Одномерные массивы — векторы
В традиционной математике «вектор» — набор пронумерованных последовательных значений, записанных в одну строку. Это полностью совпадает с тем, как выглядит самый простой однотипный массив.
Массив-список в Python:
numbers = [10, 20, 30, 40]
Каждому элементу в таком массиве соответствует один индекс-номер. Чтобы достать нужный элемент, мы пишем название массива и указываем индекс. Чтобы взять 1-й элемент, пишем так:
numbers[0]
Многомерные массивы — матрицы
Многомерный массив выглядит как таблица-матрица, и иногда его так и называют.
Ещё такие массивы называют вложенными из-за реализации в коде: для его создания внутри массива создаются ещё несколько. Каждый массив внутри будет отдельной строкой, поэтому у всех строк будут свои индексы, а у элементов внутри строк — свои.
Звучит непонятно, поэтому вот наглядный пример матрицы в Python:
matrix = [
[1, 2, 3],
[4, 5, 6],
[7, 8, 9]
]
Здесь есть три строки:
- Первая: 1, 2, 3.
- Вторая: 4, 5, 6.
- Третья: 7, 8, 9.
Для использования нужного элемента сначала нужно указать номер строки, а потом — номер внутри строки. Для получения числа 5 нужно написать:
matrix[1][1]
Это будет означать 2-ю строку, 2-й столбец.
Статический массив
Статичность — свойство классического массива, который нельзя изменять после создания.
Списки в Питоне и других популярных универсальных языках не подходят под это определение, потому что их можно менять: удалять, добавлять и заменять элементы.
Поэтому вот пример статического массива на C++:
int values[5] = {1, 2, 3, 4, 5};
Эти числа можно брать для работы в других частях программы, но как-то изменить этот набор значений невозможно.
Ещё здесь сразу видно, что работать в C++ немного сложнее, чем в Python: нужно указать тип значений и длину массива. С другой стороны, это сразу заставляет думать заранее о целях своего приложения и делает работу программы быстрее.
Динамический массив
Это массив, который может менять свою длину во время работы программы.
Динамический массив удобнее, но немного медленнее статического. Ещё работать с ним часто гораздо сложнее, если разработчик пишет код на языке, в котором существуют статические массивы и строгое разделение данных по типам.
Современный способ создания динамического массива в C++ выглядит так:
// подключаем дополнительные библиотеки vector и iostream
#include <vector>
#include <iostream>
int main() {
// создаём динамический массив сразу с начальными значениями
std::vector<int> arr = {10, 20, 30};
// добавляем новые элементы (вектор автоматически увеличивает размер)
arr.push_back(40);
arr.push_back(50);
// exit main — память автоматически освобождается
return 0;
}
При этом динамический массив всё равно может хранить только один тип элементов. Поэтому нельзя сказать, что он переменный или гибкий.
Почему все массивы разные
Из-за того, что языки создавались с разными целями, главная идея их реализации сказалась на всей технологии в целом.
Некоторые языки нужны для максимальной скорости и производительности: C, C++, Rust. В этих технологиях работать сложнее, но зато всё находится под контролем разработчика, и можно написать по-настоящему производительную программу. У других языков, таких как Python, корень философии — в удобстве и скорости работы именно программиста, но не самой программы. Поэтому там многое уже сделано за разработчика, но при этом накладывает ограничения на финальное приложение.
Основные операции с массивами
Мы посмотрим на основные операции с массивами на примере двух языков: Python и C++.
Работа в Python проще, но его производительность сильно ограничена именно из-за простоты и универсальности. Механизмы, которые делают написание кода быстрым и удобным, одновременно загружают систему и не дают оптимизировать программу выше определённого уровня. Возможности C++ огромны, но при этом сильно возрастает возможность совершить ошибку в программе.
Создание массива, добавление и удаление элементов и поиск на Python
Объявляем список в Python:
writers = ["Hemingway", "Fitzgerald", "Faulkner", "Steinbeck"]
Добавить элемент в список можно так:
# добавляем новый элемент в конец списка
writers.append("Twain")
Здесь мы указываем название списка и через точку добавляем метод для внесения нового элемента .append. В скобках говорим, что именно нужно добавить.
Удаление происходит похожим образом: мы вызываем через точку метод .remove и прописываем элемент для удаления. Это называется «удалить по значению»:
# удаляем элемент по значению
writers.remove("Faulkner")
Есть ещё один вариант удаления — указать его индекс, вызвав встроенную функцию del:
# удаляем первый элемент по индексу
del writers[0]
Команда для поиска элемента будет такой:
# ищем писателя в списке
# в результате получаем индекс или ошибку,
# если такого элемента нет
index = writers.index("Steinbeck")
Создание массива, добавление и удаление элементов и поиск на C++
Для добавления и удаления элементов в C++ нам понадобится динамический массив.
Работать на C++ немного сложнее, поэтому мы сделаем один фрагмент кода, а потом разберём, как он работает:
// подключаем vector, chrono и cstddef
#include <vector>
#include <chrono>
int main() {
// создаём вектор с датами рождения четырёх американских писателей
std::vector<std::chrono::year_month_day> birthdays = {
std::chrono::year{1899}/7/21, // Ernest Hemingway
std::chrono::year{1896}/9/24, // F. Scott Fitzgerald
std::chrono::year{1897}/9/25, // William Faulkner
std::chrono::year{1902}/2/27 // John Steinbeck
};
// добавляем новую дату рождения
birthdays.push_back(std::chrono::year{1835}/11/30); // Mark Twain
// удаляем вторую дату рождения по индексу
birthdays.erase(birthdays.begin() + 1);
// ищем элемент
std::chrono::year_month_day target = std::chrono::year{1902}/2/27;
std::size_t found_index = 0;
// перебираем вектор, чтобы найти нужную дату
for (std::size_t i = 0; i < birthdays.size(); i++) {
if (birthdays[i] == target) {
found_index = i;
break;
}
}
// выходим из программы
return 0;
}
Что мы тут делаем:
- Подключаем дополнительные модули
vectorиchronoв программу для работы с динамическим массивом и работой с форматом дат. - Объявляем главную функцию
int main(), внутри которой будет работать основная программа. В C++ всё начинается с неё. - Создаём массив из 4 значений. Для этого нужна длинная команда
std::vector<std::chrono::year_month_day> birthdays. - Новый элемент добавляем командой
birthdays.push_back. - Для удаления используем команду
birthdays.erase.
Поиск выглядит особенно сложно, поэтому его разберём подробно:
// создаём объект target — дату, которую мы хотим найти в массиве
std::chrono::year_month_day target = std::chrono::year{1902}/2/27;
// создаём переменную found_index, в которой будем хранить индекс найденного элемента
std::size_t found_index = 0;
// начинаем цикл: перебираем все элементы массива birthdays по индексам
for (std::size_t i = 0; i < birthdays.size(); i++) {
// проверяем, совпадает ли текущий элемент массива с искомой датой target
if (birthdays[i] == target) {
// если совпадает — сохраняем индекс найденного элемента
found_index = i;
// прерываем цикл, потому что дальше искать не нужно
break;
}
}
Поиск элемента и доступ по индексу
Это две разные операции, поэтому поиск выглядит сложнее.
Доступ по индексу — быстрая операция прямого получения элемента массива. При этом обработки значений вообще не происходит, потому что программа просто берёт элемент по адресу. Поиск нужен в обратной ситуации: если мы хотим найти элемент в массиве, а его индекс неизвестен. Тогда нужно перебрать массив и сравнить все элементы с нужным.
Плюсы и минусы использования массивов
Как и у каждой технологии, у массивов тоже есть слабые стороны.
Скорость доступа к элементам
Это главное преимущество массива, потому что все элементы хранятся в памяти подряд и компьютер легко может найти нужное значение по формуле. Получается, что программе не нужно ничего вычислять и перебирать, а достаточно сделать одно простое действие.
Ограничения массива и чем их заменить
Минусы массива зависят его типа:
- У статического массива фиксированная длина, и его элементы нельзя изменять.
- После удаления значения всем остальным элементам нужно сдвинуться влево. На это уходит время и ресурсы.
- Для поиска элемента нужно перебрать весь массив, каждый раз сравнивая значения. Это долго.
- В сложных языках массив может хранить только один тип значений. Это хорошо для памяти, но не всегда удобно для логики работы программы.
Лучше всего массивы заменяют технологии из удобных универсальных языков. В списках Python можно хранить любой тип данных, а ещё они изменяемые. Но зато работа программы будет не такой быстрой, поэтому одного идеального решения всё равно нет.
В Python вообще много удобных коллекций, которые хороши в разных ситуациях и про которые мы уже рассказывали: списки, множества, словари.
Для успешной программы нужно понимать её цели и выбирать язык и функции конкретно под задачу. Если хотите научиться разбираться в этом и создавать быстрые приложения, приходите на курсы Практикума. Там можно выбрать направление по вкусу и попробовать его на практике бесплатно. После курса будут проекты в портфолио и понимание новой специальности — а дальше всё ограничено только вашим воображением и идеями.
Полезный блок со скидкой
Если вам интересно разбираться со смартфонами, компьютерами и прочими гаджетами и вы хотите научиться создавать софт под них с нуля или тестировать то, что сделали другие, — держите промокод Практикума на любой платный курс: KOD (можно просто на него нажать). Он даст скидку при покупке и позволит сэкономить на обучении.
Бесплатные курсы в Практикуме тоже есть — по всем специальностям и направлениям, начать можно в любой момент, карту привязывать не нужно, если что.