Массивы
Чему вы научитесь:
- создавать массив, читать и менять его элементы по индексу;
- обходить массив циклами
forиforeach; - объяснять, почему после
int[] b = a;у одного массива два имени; - сортировать массив, искать в нём и брать его части через
^1и1..3.
![Ряд из трёх шкафчиков scores с номерами 0 1 2: шкафчик 1 открыт, на дверце бирка scores[1], а четвёртого места нет](/course-covers/csharp-beginners/06-arrays.webp)
Представьте ряд одинаковых шкафчиков в раздевалке бассейна. На каждой дверце номер, и нумерация начинается с нуля: шкафчик 0, шкафчик 1, шкафчик 2. Чтобы положить вещь или забрать её, достаточно назвать номер. Сколько шкафчиков в ряду, решают, когда ряд ставят, и пристроить к нему ещё один потом нельзя.
Зачем такой ряд программе? Если нужно хранить баллы 3 учеников, можно завести 3 переменные: score1, score2 и score3. Но для 30 учеников понадобится 30 имён, и цикл не сможет пройти по ним: номер в имени переменной нельзя подставить из счётчика.
Такой ряд в C# называется массивом: это набор переменных одного типа под одним именем. Каждая переменная ряда — элемент массива, а её номер — индекс.
int[] scores = [90, 75, 88];
Console.WriteLine(scores[0]); // 90
Console.WriteLine(scores[2]); // 88
scores[1] = 80;
Console.WriteLine(scores[1]); // 80
Console.WriteLine(scores.Length); // 3Давайте разберём программу по строкам:
int[] scoresобъявляет переменную для массива. Типint[]читается как «массив чиселint»: квадратные скобки после типа означают массив.[90, 75, 88]создаёт массив из трёх элементов и кладёт в них эти числа по порядку.scores[0]— элемент с индексом0, то есть первый. Программа печатает90.scores[2]— третий и последний элемент,88.scores[1] = 80;кладёт новое значение во второй элемент, а остальные не трогает.scores.Length— длина массива, число его элементов:3.
Индексы начинаются с нуля
В массиве из трёх элементов индексы 0, 1 и 2. Индекс последнего элемента на единицу меньше длины: scores.Length - 1.
Почему с нуля? Индекс показывает, на сколько элементов нужно отступить от начала массива. Первый элемент стоит в самом начале, отступать не нужно, поэтому его индекс 0.
Как создать массив
Перечень значений
В перечне [90, 75, 88] значения стоят в квадратных скобках через запятую, а длину компилятор считает сам. Такая форма появилась в C# 12. В коде постарше тот же массив пишут как new int[] { 90, 75, 88 }.
У перечня в квадратных скобках нет собственного типа: его задаёт объявление слева. Поэтому var scores = [90, 75, 88]; не скомпилируется, и компилятор сообщит об ошибке CS9176.
Массив заданной длины
Если значения станут известны позже, массив создают по длине: new int[3]. Каждый элемент такого массива уже получил значение:
int[] counts = new int[3];
Console.WriteLine(counts[0]); // 0
counts[2] = 7;
Console.WriteLine(counts[2]); // 7
bool[] flags = new bool[2];
Console.WriteLine(flags[1]); // FalseНовый массив чисел заполнен нулями, а массив bool — значениями false. Длина может быть и переменной: new int[n] создаёт массив из n элементов. Но после создания она не меняется.
Здесь аналогия со шкафчиками неточна. Настоящий шкафчик бывает пустым, а элемент массива — нет: в нём всегда лежит значение, хотя бы ноль.
Обход в цикле for
Индекс может быть переменной. Поэтому цикл for проходит по всему массиву: его счётчик i по очереди принимает значения всех индексов.
int[] scores = [90, 75, 88];
for (int i = 0; i < scores.Length; i++)
{
Console.WriteLine(i + ": " + scores[i]);
}
// 0: 90
// 1: 75
// 2: 88Разберём заголовок цикла:
int i = 0— счётчик начинает с индекса первого элемента;i < scores.Length— цикл продолжается, пока индекс меньше длины: последний индекс2, а приi, равном3, цикл заканчивается;i++— после каждой итерации счётчик переходит к следующему индексу.
Условие пишут именно через <, а не через <=. С <= счётчик дойдёт до индекса 3, которого в массиве нет.
Частая ошибка
Последний элемент попытались прочитать по индексу, равному длине:
int[] scores = [90, 75, 88];
Console.WriteLine(scores[scores.Length]); // ✗Unhandled exception. System.IndexOutOfRangeException: Index was outside the bounds of the array.Программа компилируется, но при запуске останавливается на этой строке с исключением IndexOutOfRangeException. Строки до неё успевают выполниться, а строки после — нет. Последний элемент — scores[scores.Length - 1].
На собеседовании часто спрашивают, что будет при выходе за границу массива. C# проверяет индекс при каждом обращении: если он меньше нуля или не меньше длины, программа останавливается с этим исключением. Компилятор такую ошибку не ловит: он не следит, какой длины массив лежит в переменной.
Главное
- Массив — ряд элементов одного типа под одним именем;
int[]— массив чиселint. - Индексы начинаются с нуля: у первого элемента индекс
0, у последнего —Length - 1. [90, 75, 88]создаёт массив из перечисленных значений,new int[3]— из трёх нулей; длина массива после создания не меняется.- Индекс за границей массива останавливает программу с исключением
IndexOutOfRangeException.