Перебор массивов. Цикл foreach

Цикл foreach предназначен для перебора элементов в контейнерах, в том числе в массивах. Формальное объявление цикла foreach:

foreach (тип_данных название_переменной in контейнер)

Например:

int[] numbers = new int[] { 1, 2, 3, 4, 5 };

foreach (int i in numbers)

{

Console.WriteLine(i);

}

Здесь в качестве контейнера выступает массив данных типа int. Поэтому мы объявляем переменную с типом int

Подобные действия мы можем сделать и с помощью цикл for:

int[] numbers = new int[] { 1, 2, 3, 4, 5 };

for (int i = 0; i < numbers.Length; i++)

{

Console.WriteLine(numbers[i]);

}

В то же время цикл for более гибкий по сравнению с foreach. Если foreach последовательно извлекает элементы контейнера и только для чтения, то в цикле for мы можем перескакивать на несколько элементов вперед в зависимости от приращения счетчика, а также можем изменять элементы:

int[] numbers = new int[] { 1, 2, 3, 4, 5 };

for (int i = 0; i < numbers.Length; i++)

{

numbers[i] = numbers[i] * 2;

Console.WriteLine(numbers[i]);

}

Многомерные массивы

Массивы бывают многомерными. В предыдущих примерах мы создавали одномерные массивы, а теперь создадим двухмерный:

int[] nums1 = new int[] { 0, 1, 2, 3, 4, 5 };

int[,] nums2 = { { 0, 1, 2 }, { 3, 4, 5 } };

Визуально оба массива можно представить следующим образом:

Одномерный массив nums1

Двухмерный массив nums2

Поскольку массив nums2 двухмерный, он представляет собой простую таблицу. Объявление трехмерного массива могло бы выглядеть так:

int[,,] nums3 = new int[2, 3, 4];

Все возможные способы определения двухмерных массивов:

int[,] nums1;

int[,] nums2 = new int[2, 3];

int[,] nums3 = new int[2, 3] { { 0, 1, 2 }, { 3, 4, 5 } };

int[,] nums4 = new int[,] { { 0, 1, 2 }, { 3, 4, 5 } };

int[,] nums5 = new [,]{ { 0, 1, 2 }, { 3, 4, 5 } };

int[,] nums6 = { { 0, 1, 2 }, { 3, 4, 5 } };

Определенную сложность может представлять перебор многомерного массива. Прежде всего надо учитывать, что длина такого массива - это совокупное количество элементов.

int[,] mas = { { 1, 2, 3 }, { 4, 5, 6 }, { 7, 8, 9 }, { 10, 11, 12 } };

foreach (int i in mas)

Console.Write($"{i} ");

Console.WriteLine();

В данном случае длина массива mas равна 12. И цикл foreach выводить все элементы массива в строку:

Но что если мы хотим отдельно пробежаться по каждой строке в таблице? В этом случае надо получить количество элементов в размерности. В частности, у каждого массива есть метод GetUpperBound(dimension), который возвращает индекс последнего элемента в определенной размерности. И если мы говорим непосредственно о двухмерном массиве, то первая размерность (с индексом 0) по сути это и есть таблица. И с помощью выражения mas.GetUpperBound(0) + 1 можно получить количество строк таблицы, представленной двухмерным массивом. А через mas.Length / rows можно получить количество элементов в каждой строке:

int[,] mas = { { 1, 2, 3 }, { 4, 5, 6 }, { 7, 8, 9 }, { 10, 11, 12 } };

int rows = mas.GetUpperBound(0) + 1;

int columns = mas.Length / rows;

for (int i = 0; i < rows; i++)

{

for (int j = 0; j < columns; j++)

{

Console.Write($"{mas[i, j]} \t");

}

Console.WriteLine();

}

Структуры

Кроме базовых элементарных типов данных и перечислений в C# имеется и составной тип данных, который называется структурой. Структуры могут содержать в себе обычные переменные и методы.

Для примера [5] создадим структуру Book, в которой будут храниться переменные для названия, автора и года издания книги. Кроме того, структура будет содержать метод для вывода информации о книге на консоль:

struct Book

{

public string name;

public string author;

public int year;

public void Info()

{

Console.WriteLine($"Книга '{name}' (автор {author}) была издана в {year} году");

}

}

Чтобы можно было использовать переменные и методы структуры из любого места программы мы ставим перед переменными и методом модификатор доступа public

Используем структуру на практике:

using System;

namespace Structures

{

class Program

{

static void Main(string[] args)

{

Book book;

book.name = "Война и мир";

book.author = "Л. Н. Толстой";

book.year = 1869;

//Выведем информацию о книге book на экран

book.Info();

Console.ReadLine();

}

}

struct Book

{

public string name;

public string author;

public int year;

public void Info()

{

Console.WriteLine($"Книга '{name}' (автор {author}) была издана в {year} году");

}

}

}

Структуру можно задать как внутри пространства имен (как в данном случае), так и внутри класса, но не внутри метода.

По сути структура Book представляет новый тип данных. Мы также можем использовать массив структур:

Book[] books=new Book[3];

books[0].name = "Война и мир";

books[0].author = "Л. Н. Толстой";

books[0].year = 1869;

books[1].name = "Преступление и наказание";

books[1].author = "Ф. М. Достоевский";

books[1].year = 1866;

books[2].name = "Отцы и дети";

books[2].author = "И. С. Тургенев";

books[2].year = 1862;

foreach (Book b in books)

{

b.Info();

}

Работа со строками

Наши рекомендации