- •Глава 9. Многомерные массивы
- •9.1 Прямоугольные массивы
- •9.1.1 Объявления и инициализация
- •9.1.2 Примеры
- •9.2 Ступенчатые массивы
- •9.2.1 Объявления и инициализация
- •9.2.2 Примеры
- •9.3 Оператор цикла с перебором foreach
- •9.4 Массивы с числом размерностей больше двух
- •Контрольные вопросы
- •Варианты заданий для самостоятельной работы
- •Глава 10. Исключительные ситуации
- •10.1 Основные понятия
- •10.2 Механизм обработки исключений
- •10.3 Примеры обработки исключений
- •10.4 Оператор throw
- •10.5 Дополнительные сведения
- •Контрольные вопросы
- •Варианты заданий для самостоятельной работы
- •Глава 11. Обработка текстовой информации
- •11.1 Символьный тип char
- •11.2 Массив символов
- •11.3 Тип String
- •11.4 Класс StringBuilder
- •11.5 Форматирование строк
- •Контрольные вопросы
- •Варианты заданий для самостоятельной работы
9.2 Ступенчатые массивы
В языке С#можно создавать двумерный массив специального типа, который называется ступенчатым массивом.
Ступенчатый или невыровненный массив – это массив одномерных массивов, каждый из которых представляет собой строку. Количество элементов в разных строках может различаться. В памяти ступенчатый массив также хранится иначе, чем прямоугольный: в виде нескольких внутренних массивов, каждый из которых имеет свой размер. Для хранения ссылок на каждый из внутренних массивов выделяется отдельная область памяти.
9.2.1 Объявления и инициализация
При объявлении ступенчатого массива каждая его размерность обозначается парой квадратных скобок:
тип[ ] [ ] имя;
Общая форма записи объявления ступенчатого массива с выделением памяти под ссылки на три строки, содержащих значения целого типа:
int[][] b = new int [3][];
Не смотря на то, что такое объявление указывает количество строк в массиве, память для строк массива еще не выделена. Строки ступенчатого массива в памяти размещаются индивидуально, поэтому под каждый из одномерных массивов, составляющих ступенчатый массив, память требуется выделять явным образом, например:
Выделение памяти под 0-ю строку (5 элементов):
b[0]=new int [5];
Выделение памяти под 1-ю строку (3 элемента):
b[1] =new int [3];
Выделение памяти под 2-ю строку (4 элемента):
b[2] = new int [4];
Здесь b[0],b[1]иb[2]– это отдельные массивы, к которым можно обращаться по имени, ниже приведен пример работы со ступенчатым массивом с использованием выделения памяти под каждую строку (лист.3).
Другой способ выделения памяти:
int[] [] b = {new int[5], new int[3], new int[4]};
Kэлементу ступенчатого массива обращаются, указывая каждую размерность в своих квадратных скобках, например:
b[1][2] b[i][j] b[j][i]
В остальном использование ступенчатых массивов не отличается от использования прямоугольных.
9.2.2 Примеры
В листинге 3 продемонстрировано применение элементов класса Аrrаупри работе со ступенчатым массивом.
Листинг 3 - Использование методов класса Аrrау для обработки ступенчатого массива
using System;
namespace ConsoleApplication3
{ class Program
{ static void Main(string[] args)
{ int[][] b = new int[3][];
b[0] = new int[5] { 4, 5, 8, 3, 6 };
b[1] = new int[3] { 7, 9, 1 };
b[2] = new int[4] { 6, 5, 3, 1 };
Console.WriteLine("Исходный массив:");
for (int i = 0; i < b.Length; ++i)
{ for (int j = 1; j < b[i].Length; ++j)
Console.Write(" " + b[i][j]);
Console.WriteLine();
}
Console.WriteLine(Array.IndexOf(b[0], 8));
}
}
}
Необходимо обратить внимание на то, как внутри цикла по строкам определяется длина каждого одномерного массива (длина каждой строки массива).
Результат работы программы:
9.3 Оператор цикла с перебором foreach
Цикл перебора foreachиспользуется для просмотра всех объектов из некоторой группы данных – коллекции. В языкеС#определен ряд типов коллекций, например, коллекцией являются массивы.
Синтаксис записи цикла foreach:
foreach(тип имя_переменнойinимя коллекции) выражение;
где тип и имя_переменнойзадают тип и имя итерационной переменной, которая в процессе итераций цикла foreachполучает значения элементов коллекции, заданной своим именем.
Если в программе в качестве коллекции используется массив данных, то необходимо помнить, что тип итерационной переменной должен совпадать или быть совместимым с базовым типом массива. Необходимо также учитывать, что итерационная переменная как элемент массива доступна только для чтения, и ей нельзя присвоить новое значение, а значит с помощью этой конструкции нельзя изменить и значение элемента массива.
Рассмотрим программу поиска максимального элемента в одномерном массиве.
Листинг 4 - Использование оператора цикла foreach (одномерный массив)
using System;
namespace ConsoleApplication5
{
class Program
{
static void Main(string[] args)
{
const int n = 6;
int[] a = new int[n] { 3, 12, 5, -9, 8, -4 };
Console.WriteLine("Исходный массив:");
for (int i = 0; i < n; ++i)
Console.WriteLine("\t" + a[i]);
Console.WriteLine();
int max = a[0];
foreach (int x in a)
{
if (x > max)
max = x;
}
Console.WriteLine("Максимальный элемент = " + max);
Console.Read();
}
}
}
Как видно из текста программы цикл foreach последовательно просматривает все элементы массива а и присваивает итерационной переменной х значение очередного элемента массива. Значение х в дальнейшем используется в операторе if для коррекции переменной max.
Результат работы программы:
Следует отметить тот факт, что не всегда требуется просматривать всю коллекцию до конца, например, в задаче, где требуется найти первый отрицательный элемент. После того как отрицательный элемент найден, можно прервать работу цикла с помощью оператора break.
При работе с многомерными массивами цикл foreach возвращает элементы в порядке следования строк.
Листинг 5 - Использование оператора цикла foreach (двумерный массив)
using System;
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
const int m = 3, n = 4;
int[,] y = new int[m, n] {
{ 2, 2, 8, 9 },
{ 4, 5, 6, 2 },
{ 7, 0, 1, 1 }
};
Console.WriteLine("Исходный массив:");
for (int i = 0; i < m; ++i)
{
for (int j = 0; j < n; ++j)
Console.Write(" " + y[i, j]);
Console.WriteLine();
}
int max = y[0, 0];
foreach (int x in y){
if (x > max) max = x;
}
Console.WriteLine("Наибольший элемент в матрице " + max);
Console.Read();
}
}
}
Как видно из текста программы использование одного оператора foreach позволило заменить два вложенных оператораforв поиске наибольшего элемента двумерного массива.
Результат работы программы: