Файл: 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