Ступенчатые (jagged) массивы в Си-шарп

 

Ступенчатый (jagged) массив – это массив массивов. В нем длина каждого массива может быть разной. Примерно это выглядит так:

Пример объявления ступенчатого массива:

 

static void Main(string[] args)
{
int[][] array = new int[3][]; // объявляем массив, который содержит 3 массива
array [0] = new int[3]; //создание внутреннего массива
array [1] = new int[2];
array [2] = new int[5];
}

Доступ к элементам осуществляется по тому же принципу, как и с многомерными маcсивами, только тут уже участвуют две пары квадратных скобок (продолжение примера выше):

 

array [0][1] = 5;
array [1][1] = 8;
array [1][2] = 5; // ошибка, индекс «2» вне границ массива

Свойство Length

Все массивы являются объектами и у них есть некоторые свойства. Самым полезным для нас будет свойство Length, которое возвращает количество элементов в массиве (во всех размерностях)

 

static void Main(string[] args)
{
int[] numbers = new int[5];
int size = numbers.Length; // size = 5
}

Класс List

 

Класс List служит для работы со списками, о чем и говорит его название. Это такой «навороченный» массив. Главное отличие от простого массива в том, что он динамический – вы можете вставлять и удалять элементы в любое время, в то время как в простом массиве размер указывается при создании и сделать его больше или меньше нельзя.

 

static void Main(string[] args)
{
List<string> teams = new List<string>(); // создание списка
teams.Add("Barcelona"); // добавление элемента
teams.Add("Chelsea");
teams.Add("Arsenal");
List<string> teams2 = new List<string>() {"Dynamo", "CSKA" }; // инициализация
}

Добавление элементов

 

Для добавления элементов в список в нем реализовано несколько методов:

 

Метод Описание
Add([элемент]) добавляет элемент в конец списка
AddRange([список элементов]) добавляет в конец списка элементы указанного списка
Insert([индекс],[элемент]) вставляет элемент на позицию соответствующую индексу, все элементы «правее» будут сдвинуты на одну позицию
InsertRange([индекс], [список элементов]) то же самое, только вставляется множество элементов


Удаление элементов

 

Метод Описание
Remove([элемент]) удаляет первое вхождение указанного элемента из списка
RemoveRange([индекс], [количество]) удаляет указанное количество элементов, начиная с указанной позиции
RemoveAt([индекс]) удаляет элемент, который находится на указанной позиции
Clear() удаляет все элементы списка

Свойство Count соответствует свойству обычного массива – Length – количество элементов.

 

static void Main(string[] args)
{
List<string> teams = new List<string>() { "Inter", "Milan", "Bayern", "Juventus"};
teams.Insert(2,"Barcelona"); // вставляем в список элемент "Barcelona" на позицию 2
teams.Remove("Milan"); // удаляем первое вхождение элемента "Milan" из списка
List<string> newTeams = new List<string>() { "Liverpool", "Roma", "Borussia", "Valencia" };
teams.AddRange(newTeams); // добавляем в конец списка элементы списка newTeams
}

 

Стоит помнить, что простые массивы работают быстрее, чем списки List. Если в вашей программе не особо важна производительность и вы не работаете с большими количествами данных, то удобнее использовать список, в противном случае нужно использовать простые массивы.

Циклы.

Циклы служат для многократного повторения некоторого фрагмента кода.
В Си-шарп есть четыре оператора циклов: for, while, do-while, foreach.

Цикл for

Этот цикл используется тогда, когда наперед известно, сколько повторений нужно сделать. Он имеет следующую структуру:

 

for (инициализация счетчика; условие продолжения; итерация)
{
//блок кода, который будет повторяться
}

Пример программы, которая выводит на экран числа 0, 1, 2, 3, 4:
static void Main(string[] args)
{
for (int i = 0; i < 5; i++) // цикл выполнится 5 раз
{
Console.WriteLine(i);
}
}

Сначала происходит создание и инициализация счетчика, i=0. Дальше идет проверка условия ( i < 5), если результат будет «истина», то дальше выполняется блок кода в теле цикла. В конце итерации происходит изменение значения счетчика (в данном примере увеличение на единицу). После этого вновь происходит проверка условия и так далее. Когда условие будет «ложь», цикл работу завершит.

Пример программы, которая находит и выводит на экран сумму элементов массива:

 

static void Main(string[] args)
{
int[] numbers = { 4, 7, 1, 23, 43 };
int s = 0;
for (int i = 0; i < numbers.Length; i++)
{
s += numbers[i];
}
Console.WriteLine(s);
Console.ReadKey();
}

Пример цикла for, когда счетчик уменьшается после каждой итерации:

 

for (int i = 5; i > 0; i--) //выполнится 5 раз
{
Console.WriteLine(i);
}

Счетчик можно изменять не только на единицу. Пример программы, которая выводит чётные числа (по число 50):

 

for (int i = 0; i <= 50; i+=2) //выполнится 26 раз
{
Console.WriteLine(i);
}

Цикл while

Слово while переводится, как «пока», что хорошо его характеризует. Он продолжает выполнятся до тех пор, пока «истинно» некоторое условие. Он имеет такую структуру:

 

while (условие продолжения)
{
//блок кода, который будет повторяться
}

Сначала проверяется условие, а дальше выполняется блок кода.

Пример той же программы, которая выводит на экран числа 0, 1, 2, 3, 4:

 

int i = 0;
while (i < 5)
{
Console.WriteLine(i);
i++;
}

Цикл может выполнятся «вечно», если задать всегда истинное условие:

 

while (true)
{
Console.WriteLine("Вечный цикл");
}

Цикл do-while

 

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

 

do
{
//блок кода, который будет повторяться
}
while (условие продолжения);

Пример программы, которая не завершит работу, пока с клавиатуры не введут число 5:

 

static void Main(string[] args)
{
int number;
do
{
Console.WriteLine("Введите число 5");
number = Convert.ToInt32(Console.ReadLine());
}
while (number != 5);
}

 

Оператор break

 

Из любого цикла можно досрочно выйти, используя оператор break. Использовать данный оператор есть смысл после удовлетворения некоторого условия, иначе цикл завершится на первой итерации.

Пример программы, которая проверяет, есть ли в массиве число кратное 13-ти. Найдя такое число, нет смысла дальше проверять остальные элементы массива, и здесь мы используем оператор break:

 

static void Main(string[] args)
{
int[] numbers = { 4, 7, 13, 20, 33, 23, 54 };
bool b = false;
for (int i = 0; i < numbers.Length; i++)
{
if (numbers[i] % 13 == 0)
{
b = true;
break;
}
}
Console.WriteLine(b ? "В массиве есть число кратное 13" : "В массиве нет числа кратного 13");
Console.ReadKey();
}

Оператор continue

 

Данный оператор позволяет перейти к следующей итерации, не завершив до конца текущую.

Пример программы, которая находит сумму нечетных элементов массива:

 

static void Main(string[] args)
{
int[] numbers = { 4, 7, 13, 20, 33, 23, 54 };
int s = 0;
for (int i = 0; i < numbers.Length; i++)
{
if (numbers[i] % 2 == 0)
continue; //переход к следующей итерации
s += numbers[i];
}
Console.WriteLine(s);
Console.ReadKey();
}

Оператор цикла foreach в Си-шарп служит для перебора элементов коллекции. К коллекциям относятся массивы, списки List и пользовательские классы коллекций. В данном операторе не нужно создавать переменную-счетчик для доступа к элементам коллекции, в отличии от других циклов. Оператор foreach имеет следующую структуру:

foreach ([тип] [переменная] in [коллекция])
{
//тело цикла
}

 

Пример программы, в которой находится сумма элементов массива с использованием цикла foreach:

 

static void Main(string[] args)
{
int[] numbers = { 4, 7, 13, 20, 33, 23, 54 };
int s = 0;

foreach (int el in numbers)
{
s += el;
}
Console.WriteLine(s);
Console.ReadKey();
}

На каждой итерации в переменную el последовательно записывается элемент коллекции. На первой итерации значение переменной el равно “4” , на второй итерации - “7” и т.д.

Как и в других циклах, в foreach можно использовать операторы break и continue.

Данный оператор стоит использовать для получения (чтения) данных из коллекции. Не стоит использовать его для добавления или удаления элементов из коллекции, иначе вы получите исключение (ошибку) Collection was modified; enumeration operation may not execute.