Опубликован: 19.02.2009 | Доступ: свободный | Студентов: 3054 / 785 | Оценка: 4.35 / 4.11 | Длительность: 16:28:00
ISBN: 978-5-94774-401-9
Лекция 8:

Массивы

< Лекция 7 || Лекция 8: 123456 || Лекция 9 >
Аннотация: Данная лекция рассматривает одномерные и многомерные массивы. Приведено большое количество практических примеров и заданий.

Массив - набор элементов одного и того же типа, объединенных общим именем. Массивы в С# можно использовать по аналогии с тем, как они используются в других языках программирования. Однако С#-массивы имеют существенные отличия: они относятся к ссылочным типам данных, более того - реализованы как объекты. Фактически имя массива является ссылкой на область кучи (динамической памяти), в которой последовательно размещается набор элементов определенного типа. Выделение памяти под элементы происходит на этапе инициализации массива. А за освобождением памяти следит система сборки мусора - неиспользуемые массивы автоматически утилизируются данной системой.

Рассмотрим различные типы массивов.

Одномерные массивы

Одномерный массив - это фиксированное количество элементов одного и того же типа, объединенных общим именем, где каждый элемент имеет свой номер. Нумерация элементов массива в С# начинается с нуля, то есть, если массив состоит из 10 элементов, то его элементы будут иметь следующие номера: 0, 1, 2, 3, 4, 5, 6, 7, 8, 9.

Одномерный массив в С# реализуется как объект, поэтому его создание представляет собой двухступенчатый процесс. Сначала объявляется ссылочная переменная на массив, затем выделяется память под требуемое количество элементов базового типа, и ссылочной переменной присваивается адрес нулевого элемента в массиве. Базовый тип определяет тип данных каждого элемента массива. Количество элементов, которые будут храниться в массиве, определяется размер массива.

В общем случае процесс объявления переменной типа массив, и выделение необходимого объема памяти может быть разделено. Кроме того на этапе объявления массива можно произвести его инициализацию. Поэтому для объявления одномерного массива может использоваться одна из следующих форм записи:

Форма записи Пояснения
базовый_тип [] имя__массива;
Например:
int [] a;
Описана ссылка на одномерный массив, которая в дальнейшем может быть использована:
  1. для адресации на уже существующий массив;
  2. передачи массива в метод в качестве параметра
  3. отсроченного выделения памяти под элементы массива.
базовый_тип [] имя__массива = 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]);
}
Задание. Измените программу так, чтобы обрабатывался массив из n чисел.

Хотя при инициализации массива нет необходимости использовать операцию 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: Выход за границу диапазона");
  }
}
Задание. Добавьте в программу обработчики исключений FormatException и OutOfMemoryException. Вспомните, что они контролируют.
Массив как параметр

Так как имя массива фактически является ссылкой, то он передается в метод по ссылке и, следовательно, все изменения элементов массива, являющегося формальным параметром, отразятся на элементах соответствующего массива, являющимся фактическим параметром.

Рассмотрим пример передачи массива как параметра:

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);
  }
}
Задание. Измените программу так, чтобы метод Change удваивал значения положительных элементов массива.
< Лекция 7 || Лекция 8: 123456 || Лекция 9 >