Массивы
Инициализация массивов
Массив мало объявить, его нужно еще проинициализировать. Только тогда ранее специфицированное множество однотипных объектов будет размещено в памяти.
Определение предполагает спецификацию КОЛИЧЕСТВА объектов по каждому измерению.
ИнициализацияМассива ::= = newИнициализация ::= = ИнициализацияСписком ::= = ЗаполняющаяИнициализация ::= = ИнициализацияКопированием newИнициализация ::= new ИмяТипа СписокОписателейРазмерности ЗаполняющаяИнициализация ::= newИнициализация ИнициализацияСписком СписокОписателейРазмерности ::= [СписокОписателейРазмерности] ОписательРазмерности ОписательРазмерности ::= [СписокОписателей] | ПустойОписатель СписокОписателей ::= [СписокОписателей ,] Описатель Описатель ::= Выражение ПустойОписатель ::= [ПУСТО]
Выражение-описатель должно быть:
- целочисленным,
- с определенным значением.
В управляемой памяти нет ничего, что бы создавалось без конструктора, – даже если его присутствие не обозначено явным образом:
string s = "qwerty"; int[] intArray = {1,2,3,4,5};
Эти операторы являются всего лишь сокращенной формой следующих операторов определения:
string s = new string(new char[]{'q','w','e','r','t','y'}); int[] intArray = new int[5]{1,2,3,4,5};
К моменту создания массива должна быть определена его основная характеристика – количество составляющих данный массив элементов. Такой фокус при определении и инициализации массивов не проходит:
int x; // К моменту определения массива значение x должно быть определено! int[] arr0 = new int[x];
Так нормально! В момент определения массива CLR знает ВСЕ НЕОБХОДИМЫЕ характеристики определяемого массива:
int x = 10; int[][] arr1 = new int[x][125]; // Внимание! Для jagged такое определение недопустимо! // Нет никаких ограничений на размеры составляющих массивов. // Для каждой составляющей требуется ЯВНАЯ спецификация.
Естественно, общее количество описателей размерности должно соответствовать количеству неявных спецификаторов.
Количество составляющих массив элементов — это не всегда ВСЕ образующие массив элементы!
При определении такой конструкции, как МАССИВ МАССИВОВ, инициализирующая запись должна содержать ПОЛНУЮ информацию о характеристиках первой составляющей массива, то есть об общем количестве составляющих данный массив элементов массивов. Все остальные описатели могут оставаться пустыми.
int val1 = 100; // На этом этапе определения массива массивов // элементов типа int принципиально знание характеристик первой составляющей! // Все остальные могут быть заданы после! int [][] x0 = new int[15][]; int [][][] x1 = new int[val1][][]; int [,][] x2 = new int[val1,7][]; int [,,][,][] x3 = new int[2,val1,7][,][]; // Следующие способы объявления корректными не являются. // int [][][] y0 = new int[val1][2][]; // int [][][] y1 = new int[][2][7]; // int [,][] y2 = new int[ ,2][7]; // int [,,] y3 = new int[val1,2, ];
При такой форме определения массива предполагается многоступенчатая инициализация, при которой производится последовательная инициализация составляющих массива:
ИнициализацияСписком ::= {СписокВыражений} ::= {СписокИнициализаторовСоставляющихМассива} СписокИнициализаторовСоставляющихМассива ::= [СписокИнициализаторовСоставляющихМассива , ] ИнициализаторМассива ИнициализаторМассива ::= newИнициализация {СписокВыражений} | {СписокВыражений} СписокВыражений ::= [СписокВыражений ,] Выражение
При инициализации списком каждый элемент массива (или составляющая массива) получает собственное значение из списка:
int[] r = {val1, 1, 4, 1*val1};
Избыточная инициализация с дополнительной возможностью уточнения характеристик массива:
int[] r = new int[] {val1, 1, 4, 1*val1}; int[] t = new int[4] {val1, 1, 4, 1*val1};
В первом случае избыточная инициализация – рецидив многословия. Тип значений элементов массива определяется спецификатором массива, количество элементов массива определяется количеством элементов списка выражений.
Во втором случае избыточная инициализация – способ дополнительного контроля размеров массива. Транслятор сосчитает количество элементов списка и сопоставит его со значением описателя.