0 added
0 removed
Original
2026-01-01
Modified
2026-02-21
1
<p><a>#статьи</a></p>
1
<p><a>#статьи</a></p>
2
<ul><li>2 фев 2023</li>
2
<ul><li>2 фев 2023</li>
3
<li>0</li>
3
<li>0</li>
4
</ul><h2>Что такое массив и как он устроен</h2>
4
</ul><h2>Что такое массив и как он устроен</h2>
5
<p>Заглядываем под капот одной из главных структур данных в программировании.</p>
5
<p>Заглядываем под капот одной из главных структур данных в программировании.</p>
6
<p>Иллюстрация: Оля Ежак для Skillbox Media</p>
6
<p>Иллюстрация: Оля Ежак для Skillbox Media</p>
7
<p>Журналист, изучает Python. Любит разбираться в мелочах, общаться с людьми и понимать их.</p>
7
<p>Журналист, изучает Python. Любит разбираться в мелочах, общаться с людьми и понимать их.</p>
8
<p>В языках программирования информация представлена разными<strong>типами данных</strong>: целые числа, числа с плавающей точкой, символы, строки, булевы значения и так далее. Благодаря этому компьютер понимает, как хранить информацию и что с ней делать.</p>
8
<p>В языках программирования информация представлена разными<strong>типами данных</strong>: целые числа, числа с плавающей точкой, символы, строки, булевы значения и так далее. Благодаря этому компьютер понимает, как хранить информацию и что с ней делать.</p>
9
<p>Но есть и более сложные сущности, которые называются<strong>структурами данных</strong>. Они содержат данные, которые, как правило, связаны определённым образом. Одна из таких структур -<strong>массивы</strong>.</p>
9
<p>Но есть и более сложные сущности, которые называются<strong>структурами данных</strong>. Они содержат данные, которые, как правило, связаны определённым образом. Одна из таких структур -<strong>массивы</strong>.</p>
10
<p>В этой статье мы расскажем, что такое массивы и зачем они нужны. Если же вы хотите научиться работать с ними в коде, почитайте материалы про массивы<a>в C++</a>и <a>в Java</a>.</p>
10
<p>В этой статье мы расскажем, что такое массивы и зачем они нужны. Если же вы хотите научиться работать с ними в коде, почитайте материалы про массивы<a>в C++</a>и <a>в Java</a>.</p>
11
<p><strong>Массив в программировании</strong> - это структура данных, которая хранит упорядоченный набор однотипных элементов. Его можно представить в виде шкафчика или камеры хранения на вокзале или в магазине: набор ячеек, в каждой из которых может что-то лежать.</p>
11
<p><strong>Массив в программировании</strong> - это структура данных, которая хранит упорядоченный набор однотипных элементов. Его можно представить в виде шкафчика или камеры хранения на вокзале или в магазине: набор ячеек, в каждой из которых может что-то лежать.</p>
12
Массив можно представить как шкафчик<em>Изображение: архив автора</em><p>Как и в шкафчике, каждая ячейка массива<strong>пронумерована</strong>, номер - это её <strong>индекс</strong>. Причём счёт идёт не от единицы, а от нуля.</p>
12
Массив можно представить как шкафчик<em>Изображение: архив автора</em><p>Как и в шкафчике, каждая ячейка массива<strong>пронумерована</strong>, номер - это её <strong>индекс</strong>. Причём счёт идёт не от единицы, а от нуля.</p>
13
<p>Массивы есть в большинстве востребованных языков программирования, часто сразу в нескольких видах. Взгляните на семь самых популярных языков в <a>рейтинге TIOBE</a> - этот тип данных реализован в каждом из них.</p>
13
<p>Массивы есть в большинстве востребованных языков программирования, часто сразу в нескольких видах. Взгляните на семь самых популярных языков в <a>рейтинге TIOBE</a> - этот тип данных реализован в каждом из них.</p>
14
Индекс TIOBE<em>Инфографика:</em><a><em>TIOBE</em></a><p>При этом в разных языках программирования их <strong>могут называть по-разному</strong>и даже предлагать<strong>несколько реализаций</strong>. Например, в Python это lists (списки) и tuples (кортежи), в C++ - arrays (массивы) и vectors (векторы). Всё это массивы, но разных видов.</p>
14
Индекс TIOBE<em>Инфографика:</em><a><em>TIOBE</em></a><p>При этом в разных языках программирования их <strong>могут называть по-разному</strong>и даже предлагать<strong>несколько реализаций</strong>. Например, в Python это lists (списки) и tuples (кортежи), в C++ - arrays (массивы) и vectors (векторы). Всё это массивы, но разных видов.</p>
15
<p>Представьте: мы пишем программу, в которой будет храниться температура окружающей среды по дням за декабрь. Если не использовать массивы, для каждого значения температуры придётся создавать свою переменную.</p>
15
<p>Представьте: мы пишем программу, в которой будет храниться температура окружающей среды по дням за декабрь. Если не использовать массивы, для каждого значения температуры придётся создавать свою переменную.</p>
16
Запись погоды без использования массивов<em>Иллюстрация: Оля Ежак для Skillbox Media</em><p>Эта информация хранится разрозненно, и переменные никак не связаны друг с другом. Если мы захотим посчитать среднюю температуру за декабрь, придётся писать длинную формулу:</p>
16
Запись погоды без использования массивов<em>Иллюстрация: Оля Ежак для Skillbox Media</em><p>Эта информация хранится разрозненно, и переменные никак не связаны друг с другом. Если мы захотим посчитать среднюю температуру за декабрь, придётся писать длинную формулу:</p>
17
Расчёт средней температуры без использования массивов<em>Иллюстрация: Оля Ежак для Skillbox Media</em><p>А если вдруг окажется, что термометр даёт ошибку в +3 градуса? Чтобы исправить ошибку, придётся вручную отнимать от каждой переменной 3 - и так для каждой из 31 строки кода.</p>
17
Расчёт средней температуры без использования массивов<em>Иллюстрация: Оля Ежак для Skillbox Media</em><p>А если вдруг окажется, что термометр даёт ошибку в +3 градуса? Чтобы исправить ошибку, придётся вручную отнимать от каждой переменной 3 - и так для каждой из 31 строки кода.</p>
18
<p>Или, допустим, мы захотим учитывать температуру не только в нашем городе, но и в соседнем. Тогда в названии каждой переменной нужно будет дополнительно указывать не только дату, но и название города - так и запутаться можно.</p>
18
<p>Или, допустим, мы захотим учитывать температуру не только в нашем городе, но и в соседнем. Тогда в названии каждой переменной нужно будет дополнительно указывать не только дату, но и название города - так и запутаться можно.</p>
19
<p>Гораздо проще пойти другим путём: создать массив "Декабрь" и записывать температуру уже внутри него.</p>
19
<p>Гораздо проще пойти другим путём: создать массив "Декабрь" и записывать температуру уже внутри него.</p>
20
Запись погоды с использованием массивов<em>Иллюстрация: Оля Ежак для Skillbox Media</em><p>Так программа понимает, что эти<strong>элементы связаны между собой</strong>. Теперь мы за пару строчек кода можем найти среднемесячную температуру - достаточно сказать программе: сложи все элементы и раздели их на длину массива. Или прибавить три градуса (сказать: прибавь 3 к каждому элементу).</p>
20
Запись погоды с использованием массивов<em>Иллюстрация: Оля Ежак для Skillbox Media</em><p>Так программа понимает, что эти<strong>элементы связаны между собой</strong>. Теперь мы за пару строчек кода можем найти среднемесячную температуру - достаточно сказать программе: сложи все элементы и раздели их на длину массива. Или прибавить три градуса (сказать: прибавь 3 к каждому элементу).</p>
21
<p>Если захотим измерять температуру в другом городе, можно просто создать другой массив - и их значения точно не перемешаются.</p>
21
<p>Если захотим измерять температуру в другом городе, можно просто создать другой массив - и их значения точно не перемешаются.</p>
22
<p>При этом обратиться к температуре любого - легче лёгкого, ведь каждый элемент имеет свой индекс, как номер ячейки в камере хранения. Нужно лишь запомнить, что<strong>нумерация обычно идёт от нуля</strong>.</p>
22
<p>При этом обратиться к температуре любого - легче лёгкого, ведь каждый элемент имеет свой индекс, как номер ячейки в камере хранения. Нужно лишь запомнить, что<strong>нумерация обычно идёт от нуля</strong>.</p>
23
<p>Данные хранятся более упорядоченно, нет никакого нагромождения из десятков и сотен переменных, которые нужно держать в голове, чтобы не запутаться и не ошибиться.</p>
23
<p>Данные хранятся более упорядоченно, нет никакого нагромождения из десятков и сотен переменных, которые нужно держать в голове, чтобы не запутаться и не ошибиться.</p>
24
<p>В некоторых массивах можно хранить даже другие массивы. Например, мы можем объявить переменную Город_N_2022 и положить в неё массивы каждого из месяцев.</p>
24
<p>В некоторых массивах можно хранить даже другие массивы. Например, мы можем объявить переменную Город_N_2022 и положить в неё массивы каждого из месяцев.</p>
25
Использование массивов для записи погоды по городам<em>Иллюстрация: Оля Ежак для Skillbox Media</em><p>Массивы - очень полезный инструмент, о котором нередко спрашивают<a>на собеседованиях</a>. В разных языках программирования с ними можно совершать множество разных операций. Например, в PHP есть <a>13 способов</a> для одной только сортировки массивов.</p>
25
Использование массивов для записи погоды по городам<em>Иллюстрация: Оля Ежак для Skillbox Media</em><p>Массивы - очень полезный инструмент, о котором нередко спрашивают<a>на собеседованиях</a>. В разных языках программирования с ними можно совершать множество разных операций. Например, в PHP есть <a>13 способов</a> для одной только сортировки массивов.</p>
26
<p>Память в компьютере поделена на <strong>ячейки</strong> - фрагменты информации, которые имеют свой адрес. Можно сказать, это такой супермассив для всех данных внутри машины.</p>
26
<p>Память в компьютере поделена на <strong>ячейки</strong> - фрагменты информации, которые имеют свой адрес. Можно сказать, это такой супермассив для всех данных внутри машины.</p>
27
<p>При создании массива компьютер выделяет непрерывный участок памяти и складывает в него<strong>элементы один за другим</strong>. Рассмотрим этот процесс подробнее.</p>
27
<p>При создании массива компьютер выделяет непрерывный участок памяти и складывает в него<strong>элементы один за другим</strong>. Рассмотрим этот процесс подробнее.</p>
28
<p>Когда мы объявляем<strong>классический массив</strong>, мы также указываем его длину (сколько в нём будет элементов) и тип данных, которые будут в нём храниться. В случае массива "Декабрь" длина будет равна 31, а тип данных - float (число с плавающей запятой - мы всё-таки температуру записываем).</p>
28
<p>Когда мы объявляем<strong>классический массив</strong>, мы также указываем его длину (сколько в нём будет элементов) и тип данных, которые будут в нём храниться. В случае массива "Декабрь" длина будет равна 31, а тип данных - float (число с плавающей запятой - мы всё-таки температуру записываем).</p>
29
<p>Так как все элементы принадлежат одному типу, они занимают одинаковый объём памяти. Допустим, в нашей архитектуре числа с плавающей запятой весят 4 байта. Компьютер умножает вес одного элемента на длину списка и получает количество памяти, которое ему нужно зарезервировать:</p>
29
<p>Так как все элементы принадлежат одному типу, они занимают одинаковый объём памяти. Допустим, в нашей архитектуре числа с плавающей запятой весят 4 байта. Компьютер умножает вес одного элемента на длину списка и получает количество памяти, которое ему нужно зарезервировать:</p>
30
<p><strong>4 * 31 = 124 байта</strong></p>
30
<p><strong>4 * 31 = 124 байта</strong></p>
31
<p>И вот эти 124 соседних байта резервируются под массив "Декабрь". А до и после них в памяти могут быть какие угодно данные.</p>
31
<p>И вот эти 124 соседних байта резервируются под массив "Декабрь". А до и после них в памяти могут быть какие угодно данные.</p>
32
Ячейки памяти<em>Иллюстрация: Оля Ежак для Skillbox Media</em><p>Когда мы обращаемся к элементу массива по индексу, компьютеру нужно найти среди всей своей памяти ячейки, в которых лежит нужный элемент.</p>
32
Ячейки памяти<em>Иллюстрация: Оля Ежак для Skillbox Media</em><p>Когда мы обращаемся к элементу массива по индексу, компьютеру нужно найти среди всей своей памяти ячейки, в которых лежит нужный элемент.</p>
33
<p>Для этого он определяет<strong>начальный адрес массива</strong>. Это адрес ячейки памяти, с которой начинается массив. Если он будет 54921, то память компьютера будет выглядеть следующим образом.</p>
33
<p>Для этого он определяет<strong>начальный адрес массива</strong>. Это адрес ячейки памяти, с которой начинается массив. Если он будет 54921, то память компьютера будет выглядеть следующим образом.</p>
34
Начальный адрес массива<em>Иллюстрация: Оля Ежак для Skillbox Media</em><p>Извлечь из такой структуры элемент с нужным индексом несложно. Это делается по следующей<strong>формуле</strong>:</p>
34
Начальный адрес массива<em>Иллюстрация: Оля Ежак для Skillbox Media</em><p>Извлечь из такой структуры элемент с нужным индексом несложно. Это делается по следующей<strong>формуле</strong>:</p>
35
<p><strong>начальный адрес массива</strong>+<strong>индекс</strong>*<strong>число ячеек, которые занимает один элемент</strong></p>
35
<p><strong>начальный адрес массива</strong>+<strong>индекс</strong>*<strong>число ячеек, которые занимает один элемент</strong></p>
36
<p>Для наглядности подставим в эту формулу несколько индексов.</p>
36
<p>Для наглядности подставим в эту формулу несколько индексов.</p>
37
<p><strong>Индекс 0:</strong>54921 + 0 * 4 = 54921 + 0 = 54921</p>
37
<p><strong>Индекс 0:</strong>54921 + 0 * 4 = 54921 + 0 = 54921</p>
38
<p><strong>Индекс 1:</strong>54921 + 1 * 4 = 54921 + 4 = 54925</p>
38
<p><strong>Индекс 1:</strong>54921 + 1 * 4 = 54921 + 4 = 54925</p>
39
<p><strong>Индекс 2:</strong>54921 + 2 * 4 = 54921 + 8 = 54929</p>
39
<p><strong>Индекс 2:</strong>54921 + 2 * 4 = 54921 + 8 = 54929</p>
40
<p>За каждый индекс после нуля адрес ячейки<strong>смещается</strong>на 4, потому что именно столько весит каждый элемент массива. А если индекс равен нулю, смещения нет. Именно поэтому индексы считают с нуля, а не с единицы.</p>
40
<p>За каждый индекс после нуля адрес ячейки<strong>смещается</strong>на 4, потому что именно столько весит каждый элемент массива. А если индекс равен нулю, смещения нет. Именно поэтому индексы считают с нуля, а не с единицы.</p>
41
<p>Теперь становится понятно, почему для классических массивов нужно заранее указывать тип данных и количество элементов:</p>
41
<p>Теперь становится понятно, почему для классических массивов нужно заранее указывать тип данных и количество элементов:</p>
42
<ul><li>Если компьютер не знает тип данных, то он не понимает, сколько памяти нужно выделять под каждый элемент и на сколько ячеек смещаться при поиске элемента по индексу.</li>
42
<ul><li>Если компьютер не знает тип данных, то он не понимает, сколько памяти нужно выделять под каждый элемент и на сколько ячеек смещаться при поиске элемента по индексу.</li>
43
<li>Если компьютер не знает длину массива, то он не понимает, сколько памяти нужно под него выделить.</li>
43
<li>Если компьютер не знает длину массива, то он не понимает, сколько памяти нужно под него выделить.</li>
44
</ul><p>Классический массив понятен, предсказуем, занимает мало места и быстро работает, но и возможности его применения ограничены. Чтобы массивы были более гибкими и подходили под разные задачи, в некоторых языках программирования придумали их более сложные реализации.</p>
44
</ul><p>Классический массив понятен, предсказуем, занимает мало места и быстро работает, но и возможности его применения ограничены. Чтобы массивы были более гибкими и подходили под разные задачи, в некоторых языках программирования придумали их более сложные реализации.</p>
45
<p>Длина<strong>статического массива</strong>определена заранее. При его создании программист сразу пишет, сколько в массиве будет элементов. Если положить в него меньше элементов, чем объявлено, то в остальных будут находиться пустые значения.</p>
45
<p>Длина<strong>статического массива</strong>определена заранее. При его создании программист сразу пишет, сколько в массиве будет элементов. Если положить в него меньше элементов, чем объявлено, то в остальных будут находиться пустые значения.</p>
46
<p>Это удобно, когда программист сразу знает, сколько элементов ему нужно. Если он записывает среднесуточную температуру за каждый день в декабре, то понадобится 31 элемент, если буквы русского алфавита - 33 элемента.</p>
46
<p>Это удобно, когда программист сразу знает, сколько элементов ему нужно. Если он записывает среднесуточную температуру за каждый день в декабре, то понадобится 31 элемент, если буквы русского алфавита - 33 элемента.</p>
47
<p>Длина<strong>динамических массивов</strong>, напротив, может изменяться во время выполнения программы. Например, программа должна хранить оценки школьника по информатике. Учитель ставит новую оценку - в массив добавляется новый элемент. Так это выглядит со стороны.</p>
47
<p>Длина<strong>динамических массивов</strong>, напротив, может изменяться во время выполнения программы. Например, программа должна хранить оценки школьника по информатике. Учитель ставит новую оценку - в массив добавляется новый элемент. Так это выглядит со стороны.</p>
48
<p>На самом деле при добавлении нового элемента компьютер<strong>создаёт новый массив</strong>, в который копирует старые элементы и добавляет новые. Старый массив при этом удаляется.</p>
48
<p>На самом деле при добавлении нового элемента компьютер<strong>создаёт новый массив</strong>, в который копирует старые элементы и добавляет новые. Старый массив при этом удаляется.</p>
49
<p>Так что по сути<strong>динамический массив - это тот же статический</strong>, но способный пересоздаваться с другой длиной.</p>
49
<p>Так что по сути<strong>динамический массив - это тот же статический</strong>, но способный пересоздаваться с другой длиной.</p>
50
<p>Часто компьютер резервирует под динамические массивы немного больше места, чем нужно при создании. Он делает это для того, чтобы не пришлось пересоздавать массив, когда в него добавляют всего один или два новых элемента.</p>
50
<p>Часто компьютер резервирует под динамические массивы немного больше места, чем нужно при создании. Он делает это для того, чтобы не пришлось пересоздавать массив, когда в него добавляют всего один или два новых элемента.</p>
51
<p><strong>Однородные массивы</strong>состоят из элементов одинакового типа данных. Например, только целые числа или только строки. Хранить элементы разных типов в них нельзя.</p>
51
<p><strong>Однородные массивы</strong>состоят из элементов одинакового типа данных. Например, только целые числа или только строки. Хранить элементы разных типов в них нельзя.</p>
52
<p>В <strong>гетерогенных массивах</strong>одним элементом может быть целое число, другим - строка, третьим - вообще другой массив. Часто это может быть удобно, но среднее арифметическое всех его элементов, конечно, не посчитаешь. И ладно, если программа выдаст ошибку, - а если действительно<a>решит посчитать и выведет результат</a>?</p>
52
<p>В <strong>гетерогенных массивах</strong>одним элементом может быть целое число, другим - строка, третьим - вообще другой массив. Часто это может быть удобно, но среднее арифметическое всех его элементов, конечно, не посчитаешь. И ладно, если программа выдаст ошибку, - а если действительно<a>решит посчитать и выведет результат</a>?</p>
53
<p>На самом деле гетерогенные массивы хранят в себе<strong>не сами данные, а ссылку на них</strong>. Например, питоновский список может выглядеть так: [1, 'строка', False]. Но внутреннее его устройство сложнее: [ссылка на 1, ссылка на 'строка', ссылка на False]. А сами данные хранятся где-то ещё в разрозненном виде, никак не связанные друг с другом.</p>
53
<p>На самом деле гетерогенные массивы хранят в себе<strong>не сами данные, а ссылку на них</strong>. Например, питоновский список может выглядеть так: [1, 'строка', False]. Но внутреннее его устройство сложнее: [ссылка на 1, ссылка на 'строка', ссылка на False]. А сами данные хранятся где-то ещё в разрозненном виде, никак не связанные друг с другом.</p>
54
<p>Получается, с технической точки зрения<strong>гетерогенный массив практически не отличается от гомогенного</strong>. Он тоже хранит в себе один тип данных - ссылочный.</p>
54
<p>Получается, с технической точки зрения<strong>гетерогенный массив практически не отличается от гомогенного</strong>. Он тоже хранит в себе один тип данных - ссылочный.</p>
55
<p><strong>Одномерный массив</strong> - это ряд пронумерованных элементов. Они, как вагоны поезда, следуют друг за другом, и к ним можно обратиться по номеру: первый, второй, третий, десятый.</p>
55
<p><strong>Одномерный массив</strong> - это ряд пронумерованных элементов. Они, как вагоны поезда, следуют друг за другом, и к ним можно обратиться по номеру: первый, второй, третий, десятый.</p>
56
<p><strong>Двумерный массив</strong> - несколько рядов элементов. Его можно представить как таблицу, в которой есть строки и столбцы, а сами элементы находятся на их пересечении. Соответственно, индекс такого массива состоит из двух чисел: номера ряда (столбца) и номера элемента в этом ряду.</p>
56
<p><strong>Двумерный массив</strong> - несколько рядов элементов. Его можно представить как таблицу, в которой есть строки и столбцы, а сами элементы находятся на их пересечении. Соответственно, индекс такого массива состоит из двух чисел: номера ряда (столбца) и номера элемента в этом ряду.</p>
57
<p>С точки зрения реализации он представляет собой массив, в котором лежат одномерные массивы.</p>
57
<p>С точки зрения реализации он представляет собой массив, в котором лежат одномерные массивы.</p>
58
<p>Также бывают<strong>массивы</strong><strong>трёхмерные, четырёхмерные, пятимерные</strong>и так далее. Чем больше измерений, тем сложнее структура и тем из большего количества чисел состоят индексы элементов.</p>
58
<p>Также бывают<strong>массивы</strong><strong>трёхмерные, четырёхмерные, пятимерные</strong>и так далее. Чем больше измерений, тем сложнее структура и тем из большего количества чисел состоят индексы элементов.</p>
59
<ul><li><strong>Массив</strong> - это<strong>структура данных</strong>фиксированной длины для хранения упорядоченного набора элементов. Элементы при этом должны относиться к одному типу данных.</li>
59
<ul><li><strong>Массив</strong> - это<strong>структура данных</strong>фиксированной длины для хранения упорядоченного набора элементов. Элементы при этом должны относиться к одному типу данных.</li>
60
<li>Элементы массива физически хранятся в <strong>соседних ячейках памяти</strong>. К каждому из них можно обратиться по <strong>индексу</strong>.</li>
60
<li>Элементы массива физически хранятся в <strong>соседних ячейках памяти</strong>. К каждому из них можно обратиться по <strong>индексу</strong>.</li>
61
<li>У массива может быть<strong>более сложная реализация</strong>в зависимости от языка программирования. Длину<strong>динамического</strong>можно изменять,<strong>гетерогенные</strong>могут хранить ссылки на разные типы данных, а в <strong>многомерных</strong>каждый элемент имеет сразу несколько индексов.</li>
61
<li>У массива может быть<strong>более сложная реализация</strong>в зависимости от языка программирования. Длину<strong>динамического</strong>можно изменять,<strong>гетерогенные</strong>могут хранить ссылки на разные типы данных, а в <strong>многомерных</strong>каждый элемент имеет сразу несколько индексов.</li>
62
</ul><a><b>Бесплатный курс по Python ➞</b>Мини-курс для новичков и для опытных кодеров. 4 крутых проекта в портфолио, живое общение со спикером. Кликните и узнайте, чему можно научиться на курсе. Смотреть программу</a>
62
</ul><a><b>Бесплатный курс по Python ➞</b>Мини-курс для новичков и для опытных кодеров. 4 крутых проекта в портфолио, живое общение со спикером. Кликните и узнайте, чему можно научиться на курсе. Смотреть программу</a>