Файл: 1_C#_Введение_в_программирование_Уч_пособ_(Марченко-2005).pdf
ВУЗ: Не указан
Категория: Не указан
Дисциплина: Не указана
Добавлен: 11.12.2025
Просмотров: 1326
Скачиваний: 3
ПУСТО – оно и есть пусто.
РАЗДЕЛИТЕЛЬ – пробел, несколько пробелов, символ табуляции, символ перехода на новую строку, комбинация символов “новая строка/возврат каретки” и прочая икебана…
При объявлении массива действуют следующие правила:
Спецификатор размерности, состоящий из одного неявного спецификатора [] специфицирует составляющую массива размерности 1.
Спецификатор размерности, состоящий из N неявных спецификаторов [ ,,, … ,] специфицирует составляющую массива размерности N.
Длина списка спецификаторов размерности массива не огранена.
При этом информация о типе составляющих массива в объявлении массива определяется на основе типа массива и списка его спецификаторов размерности.
Синтаксис объявления массива (ссылки на массив) позволяет специфицировать массивы произвольной конфигурации без какого-либо намёка на количественные характеристики составляющих массивы элементов.
Ниже представлены способы ОБЪЯВЛЕНИЯ ссылок на массивы РАЗЛИЧНОЙ размерности и конфигурации.
//Объявлены ссылки на массивы размерности 3 элементов типа int.
//Это массивы составляющих, представляющих собой массивы элементов
//размерности 2 одномерных массивов элементов типа int.
//Размеры всех составляющих массивов одного уровня равны
//между собой (так называемые “прямоугольные” массивы).
int[,,] arr0; |
, |
] arr1; |
int[ , |
||
int[ |
|
|
, |
|
|
, |
|
|
] arr2; |
|
|
//Объявлена ссылка на
//ОДНОМЕРНЫЙ(!) массив
//ОДНОМЕРНЫХ(!) элементов массива, каждый из которых является
//ОДНОМЕРНЫМ(!) массивом элементов типа int. int[][][] arr3;
//Объявлена ссылка на
//ОДНОМЕРНЫЙ(!) массив составляющих, каждая из которых является
//ДВУМЕРНЫМ(!) массивом массивов элементов типа int.
//При этом никаких ограничений на размеры “прямоугольных” составляющих
//данное объявление не содержит. У всех составляющих могут быть разные
//размеры.
int[][,] arr4;
//Объявлена ссылка на
//ДВУМЕРНЫЙ(!) массив составляющих, каждая из которых является
//ОДНОМЕРНЫМ(!) массивом элементов типа int.
//При этом никаких ограничений на размеры одномерных составляющих
//данное объявление не содержит. У всех составляющих могут быть разные
//размеры.
int[,][] arr5;
Рассмотренный синтаксис объявления и инициализации массива позволяет определять ДВЕ различных категории массивов:
простые (прямоугольные) массивы,
jagged (зубчатый, зазубренный; неровно оторванный; пьяный; находящийся под
влиянием наркотиков) массивы.
Особенности инициализации и использования массивов разных категорий рассматриваются дальше.
Инициализация массивов
Массив мало объявить, его нужно ещё проинициализировать. Только тогда ранее специфицированное множество однотипных объектов будет размещено в памяти.
Определение предполагает спецификацию КОЛИЧЕСТВА объектов по каждому измерению.
ИнициализацияМассива ::= = newИнициализация ::= = ИнициализацияСписком
37
::= = ЗаполняющаяИнициализация ::= = ИнициализацияКопированием
newИнициализация ::= new ИмяТипа СписокОписателейРазмерности ЗаполняющаяИнициализация ::= newИнициализация ИнициализацияСписком
СписокОписателейРазмерности ::= [СписокОписателейРазмерности] ОписательРазмерности ОписательРазмерности ::= [СписокОписателей] | ПустойОписатель СписокОписателей ::= [СписокОписателей ,] Описатель Описатель ::= Выражение ПустойОписатель ::= [ПУСТО]
Выражение-описатель должно быть:
целочисленным,
с определённым значением.
Такой фокус при определении и инициализации массивов не проходит:
int x; // К моменту определения массива значение x должно быть определено! int[] arr0 = new int[x];
Так нормально! В момент определения массива CLR знает ВСЕ НЕОБХОДИМЫЕ характеристики определяемого массива.
int x = 10;
int[][] arr1 = new int[125][x];
Естественно, общее количество описателей размерности должно соответствовать количеству неявных спецификаторов.
ВСЕ НЕОБХОДИМЫЕ характеристики – это не всегда ВСЕ!
При определении массивов произвольной размерности инициализирующая запись должна содержать ПОЛНУЮ информацию о характеристиках первой составляющей массива. Все остальные описатели могут оставаться пустыми.
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};
38
Избыточная инициализация с дополнительной возможностью уточнения характеристик массива.
int[] r = new int[] {val1, 1, 4, 1*val1}; int[] t = new int[4] {val1, 1, 4, 1*val1};
В первом случае избыточная инициализация – рецидив многословия. Тип значений элементов массива определяется спецификатором массива, количество элементов массива определяется количеством элементов списка выражений.
Во втором случае избыточная инициализация – способ дополнительного контроля размеров массива. Транслятор сосчитает количество элементов списка и сопоставит его со значением описателя.
Инициализация многомерных массивов – дело ответственное, которое требует особого внимания и не всегда может быть компактно наглядно представлено одним оператором.
При этом само объявление оператора может содержать лишь частичную инициализацию, а может и не содержать её вовсе. Делу инициализации одного массива может быть посвящено множество операторов. В этом случае инициализирующие операторы строятся на основе операций присвоения. Главное при этом – не выходить за пределы характеристик массива, заданных при объявлении массива.
ИнициализацияКопированием ::= СпецификацияСоставляющей СпецификацияСоставляющей ::= ИмяМассива СписокИндексныхВыражений СписокИндексныхВыражений ::= [СписокИндексныхВыражений] [ИндексноеВыражение] ИндексноеВыражение ::= Выражение
В силу того, что массив является объектом ссылочного типа, составляющие одного массива могут быть использованы для инициализации другого массива. Ответственность за возможные переплетения ссылок возлагается на программиста.
int [] q = {0,1,2,3,4,5,6,7,8,9}; int [][] d1 = {
new int[3], new int[5]
};
int [][][] d2 = new int[2][][];
d2[0] = new int[50][]; d2[0][0] = d1[0];
//d2[1][0] ссылается на составляющую массива d1. d2[0][1] = new int[125];
d2[1] = new int[50][];
d2[1][1] = new int[10]{1,2,3,4,5,6,7,8,9,10}; d2[1][0] = q;
//d2[1][0] ссылается на ранее объявленный и определённый массив q.
Примеры инициализации массивов
Одномерный массив из int.
int[] myArray = new int [5];
Этот массив содержит элементы от myArray[0] до myArray[4].
Операция new используется для создания массива и инициализации его элементов предопределёнными значениями. В результате выполнения этого оператора все элементы массива будут установлены в ноль.
Простой строковый массив можно объявить и проинициализировать аналогичным образом:
string[] myStringArray = new string[6];
Пример совмещения явной инициализации элементов массива с его объявлением. При этом спецификатора размерности не требуется, поскольку соответствующая информация может быть получена непосредственно из инициализирующего списка. Например:
39
int[] myArray = new int[] {1, 3, 5, 7, 9};
Строковый массив может быть проинициализирован аналогичным образом:
string[] weekDays = new string[] {”Sun”,”Sat”,”Mon”,”Tue”,”Wed”,”Thu”,”Fri”};
И это не единственный способ объявления и инициализации.
Если объявление совмещается с инициализацией, операция new может быть опущена. Предполагается, что транслятор знает, что при этом нужно сделать:
string[] weekDays = {”Sun”,”Sat”,”Mon”,”Tue”,”Wed”,”Thu”,”Fri”};
Объявление и инициализация вообще могут быть размещены в разных операторах. Но в этом случае без операции new ничего не получится:
int[] myArray;
myArray = new int[] {1, 3, 5, 7, 9}; // Так можно. myArray = {1, 3, 5, 7, 9}; // Так нельзя.
Два типа массивов: Value Type and Reference Type
Рассмотрим следующее объявление:
MyType[] myArray = new MyType[10];
Результат выполнения этого оператора зависит от того, что собой представляет тип MyType.
Возможны всего два варианта: MyType может быть размерным или ссылочным типом.
Если это тип размерный, результатом выполнения оператора будет массив, содержащий 10 объектов MyType.
Если MyType является ссылочным типом, то в результате выполнения данного оператора будет создан массив из 10 элементов типа ссылка, каждый из которых будет проинициализирован пустой ссылкой – значением null.
Доступ к элементам массива реализуется в соответствии с правилом индексации
– по каждому измерению индексация осуществляется с НУЛЯ до n-1, где n – количество элементов размерности.
Ещё один пример совмещения инициализации массива с его передачей как параметра методу. Перебор элементов массива реализуется в соответствии с правилом индексации:
using System;
public class ArrayClass
{
static void PrintArray(int[,] w)
{
// Display the array elements: for (int i=0; i < 4; i++)
for (int j=0; j < 2; j++) Console.WriteLine(“Element({0},{1})={2}”, i, j, w[i,j]);
}
public static void Main()
{
// Pass the array as a parameter:
PrintArray(new int[,] {{1,2}, {3,4}, {5,6}, {7,8}});
}
}
Встроенный сервис по обслуживанию простых массивов
При работе с массивами следует иметь в виду одно важное обстоятельство.
В .NET ВСЕ массивы происходят от ОДНОГО общего (базового) класса Array. Это означает, что ВСЕ созданные в программе массивы обеспечиваются специальным
40