Основы программирования на C#


Массивы массивов - часть 2


В этом случае элементы массива получат при инициализации нулевые значения. Реальную инициализацию нужно будет выполнять программным путем. Стоит заметить, что в конструкторе верхнего уровня константу 3 можно опустить и писать просто new int[][]. Самое забавное, что вызов этого конструктора можно вообще опустить - он будет подразумеваться:

int[][] jagger2 = { new int[4], new int[2], new int[3] };

А вот конструкторы нижнего уровня необходимы. Еще одно важное замечание - динамические массивы возможны и здесь. В общем случае, границы на любом уровне могут быть выражениями, зависящими от переменных. Более того, допустимо, чтобы массивы на нижнем уровне были многомерными. Но это уже "от лукавого" - вряд ли стоит пользоваться такими сложными структурами данных, ведь с ними предстоит еще и работать.

Приведу теперь чуть более реальный пример, описывающий простое генеалогическое дерево, которое условно назову "отцы и дети":

//массив массивов -"Отцы и дети" int Fcount =3; string[] Fathers = new string[Fcount]; Fathers[0] ="Николай"; Fathers[1] = "Сергей"; Fathers[2] = "Петр"; string[][] Children = new string[Fcount][]; Children[0] = new string[] {"Ольга", "Федор"}; Children[1] = new string[] {"Сергей","Валентина","Ира","Дмитрий"}; Children[2] = new string[]{"Мария","Ирина","Надежда"}; myar.PrintAr3(Fathers,Children);

Здесь отцов описывает обычный динамический одномерный массив Fathers. Для описания детей этих отцов необходим уже массив массивов, который также является динамическим на верхнем уровне, поскольку число его элементов совпадает с числом элементов массива Fathers. Здесь показан еще один способ создания таких массивов. Вначале конструируется массив верхнего уровня, содержащий ссылки со значением void. А затем на нижнем уровне конструктор создает настоящие массивы в динамической памяти, с которыми и связываются ссылки.

Я не буду демонстрировать работу с генеалогическим деревом, ограничусь лишь печатью этого массива. Здесь есть несколько поучительных моментов. В классе Arrs для печати массива создан специальный метод PrintAr3, которому в качестве аргументов передаются массивы Fathers и Children. Вот текст данной процедуры:

public void PrintAr3(string [] Fathers, string[][] Children) { for(int i = 0; i < Fathers.Length; i++) { Console.WriteLine("Отец : {0}; Его дети:", Fathers[i]); for(int j = 0; j < Children[i].Length; j++) Console.Write( Children[i][j] + " "); Console.WriteLine(); } }//PrintAr3

Приведу некоторые комментарии к этой процедуре:

  • Внешний цикл по i организован по числу элементов массива Fathers. Заметьте, здесь используется свойство Length, в отличие от ранее применяемого метода GetLength.
  • В этом цикле с тем же успехом можно было бы использовать и имя массива Children. Свойство Length для него возвращает число элементов верхнего уровня, совпадающее, как уже говорилось, с числом элементов массива Fathers.
  • Во внутреннем цикле свойство Length вызывается для каждого элемента Children[i], который является массивом.
  • Остальные детали, надеюсь, понятны.

Приведу вывод, полученный в результате работы процедуры PrintAr3.

Дерево "Отцы и дети"

Рис. 11.3.  Дерево "Отцы и дети"




Начало  Назад  Вперед