Массивы
Массив - набор элементов одного и того же типа, объединенных общим именем. Массивы в С# можно использовать по аналогии с тем, как они используются в других языках программирования. Однако С#-массивы имеют существенные отличия: они относятся к ссылочным типам данных, более того - реализованы как объекты. Фактически имя массива является ссылкой на область кучи (динамической памяти), в которой последовательно размещается набор элементов определенного типа. Выделение памяти под элементы происходит на этапе инициализации массива. А за освобождением памяти следит система сборки мусора - неиспользуемые массивы автоматически утилизируются данной системой.
Рассмотрим различные типы массивов.
Одномерные массивы
Одномерный массив - это фиксированное количество элементов одного и того же типа, объединенных общим именем, где каждый элемент имеет свой номер. Нумерация элементов массива в С# начинается с нуля, то есть, если массив состоит из 10 элементов, то его элементы будут иметь следующие номера: 0, 1, 2, 3, 4, 5, 6, 7, 8, 9.
Одномерный массив в С# реализуется как объект, поэтому его создание представляет собой двухступенчатый процесс. Сначала объявляется ссылочная переменная на массив, затем выделяется память под требуемое количество элементов базового типа, и ссылочной переменной присваивается адрес нулевого элемента в массиве. Базовый тип определяет тип данных каждого элемента массива. Количество элементов, которые будут храниться в массиве, определяется размер массива.
В общем случае процесс объявления переменной типа массив, и выделение необходимого объема памяти может быть разделено. Кроме того на этапе объявления массива можно произвести его инициализацию. Поэтому для объявления одномерного массива может использоваться одна из следующих форм записи:
Форма записи | Пояснения |
---|---|
базовый_тип [] имя__массива; int [] a; |
Описана ссылка на одномерный массив, которая в дальнейшем может быть использована:
|
базовый_тип [] имя__массива = new базовый_тип [размер]; int []a=new int [10]; |
Объявлен одномерный массив заданного типа и выделена память под одномерный массив указанной размерности. Адрес данной области памяти записан в ссылочную переменную. Элементы массива равны нулю.
Замечание. Надо отметить, что в C# элементам массива присваиваются начальные значения по умолчанию в зависимости от базового типа. Для арифметических типов - нули, для ссылочных типов - null, для символов - пробел.
|
базовый_тип [] имя__массива={список инициализации}; int []a={0, 1, 2, 3}; |
Выделена память под одномерный массив, размерность которого соответствует количеству элементов в списке инициализации. Адрес этой области памяти записан в ссылочную переменную. Значение элементов массива соответствует списку инициализации. |
Обращения к элементам массива происходит с помощью индекса, для этого нужно указать имя массива и в квадратных скобках его номер. Например, a[0], b[10], c[i].
Так как массив представляет собой набор элементов, объединенных общим именем, то обработка массива обычно производится в цикле. Рассмотрим несколько простых примеров работы с одномерными массивами.
Пример 1.
static void Main() { int[] myArray = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }; int i; for (i = 0; i < 10; ++i) Console.WriteLine(myArray[i]); }
Пример 2.
static void Main() { int[] myArray = new int[10]; int i; for (i = 0; i < 10; i++) myArray[i] = i * i; for (i = 0; i < 10; i++) Console.WriteLine(myArray[i]); }
Хотя при инициализации массива нет необходимости использовать операцию new, все же массив можно инициализировать следующим образом:
int [ ] myArray = new int [ ] { 99, 10, 100, 18, 78, 23, 163, 9, 87, 49 };
Несмотря на избыточность, данная форма инициализации массива может оказаться полезной в том случае, когда уже существующей ссылке на одномерный массив присваивается ссылка на новый массив. Например:
static void Main() { int[] myArray = { 0, 1, 2, 3, 4, 5}; int i; for (i = 0; i < 6; i++) Console.Write(" "+myArray[i]); Console.WriteLine("\nНовый массив: "); myArray = new int[] { 99, 10, 100, 18, 78, 23, 163, 9, 87, 49 }; // 1 for (i = 0; i < 10; i++) Console.Write(" " + myArray[i]); }
Следует отметить, что первоначально переменная myArray ссылалась на 6-ти элементный массив. В строке 1 переменной myArray была присвоена ссылка на новый 10-элементный массив, в результате чего исходный массив оказался неиспользуемым, т.к. на него теперь не ссылается ни один объект. Поэтому он автоматически будет удален сборщиком мусора.
Массивы и исключения
Выход за границы массива в C# расценивается как ошибка, в ответ на которую генерируется исключение - IndexOutOfRangeException.
Рассмотрим следующий пример:
static void Main() { int[] myArray = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }; int i; try { for (i = 0; i <= 10; i++) Console.WriteLine(myArray[i]); } catch (IndexOutOfRangeException) { Console.WriteLine("Exception: Выход за границу диапазона"); } }
Массив как параметр
Так как имя массива фактически является ссылкой, то он передается в метод по ссылке и, следовательно, все изменения элементов массива, являющегося формальным параметром, отразятся на элементах соответствующего массива, являющимся фактическим параметром.
Рассмотрим пример передачи массива как параметра:
class Program { static void Print(int n, int[] a) //n - размерность массива, а - ссылка на массив { for (int i = 0; i < n; i++) Console.Write("{0} ", a[i]); Console.WriteLine(); } static void Change(int n, int[] a) { for (int i = 0; i < n; i++) if (a[i] > 0) a[i] = 0; // изменяются элементы массива } static void Main() { int[] myArray = { 0, -1, -2, 3, 4, 5, -6, -7, 8, -9 }; Print(10, myArray); Change(10, myArray); Print(10, myArray); } }