Массивы

Массив — это совокупность данных одного типа, имеющих одно общее имя. Доступ к элементам массива осуществляется путём указания имени массива и номера элемента.

Особенностью массивов в C# относительно языков C/C++ является то, что память под них всегда выделяется динамически. Это объясняется тем, что любой массив является наследником класса Array.

Вначале рассмотрим работу с одномерным массивом, затем рассмотрим приёмы работы с двухмерными и многомерными массивами.

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

Одномерный массив — это массив, имеющий одно измерение.

Прежде чем начать работать с массивом, необходимо создать ссылку на объект:

тип_элементов [] имя_массива;

Затем выделяется память под заданное количество элементов массива:

имя_массива = new тип_элементов[количество_элементов];

После этого с массивом можно выполнять какие-либо действия.

Например, создадим массив из 5 вещественных чисел:

double [] x;

x = new double[5];

Две рассмотренные выше операции можно объединить:

double [] x = new double[5];

Как и простую переменную, массив можно инициализировать, т.е. задать элементам массива начальные значения (пусть это будут числа 4,5,3,2,1):

double []x = new double[5] {4,5,3,2,1};

Если чисел при инициализации задать больше или меньше необходимого, то система на этапе компиляции выдаст ошибку. Вывод: данных при инициализации надо задавать ровно столько, сколько выделяем памяти.

Полученную запись можно упростить:

double []x = {4,5,3,2,1};

Здесь память под массив будет выделяться по фактическому количеству данных, записанных в блоке (фигурных скобках).

В обоих случаях выделяется память под массива из 5 элементов вещественного типа.

К стати. А как система отреагирует вот на такую запись:

double []x = {};

Оказывается, совершенно спокойно. Точно так же её вполне устроит и такое:

double []x = new double[0];

Массив из нуль чисел — это тоже массив. Создать его можно, а вот обращаться к данным этого массива не получится. Отрицательное же количество элементов оценивается как ошибочное. Ни создать такой массив, и тем более работать с ним не выйдет. Компилятор сразу выдаст ошибку.

Дальнейшая работа с массивом ведётся так же, как обычно это было в C/C++. После выхода из блока, в котором был создан массив, выделенная под массив память освобождается «сборщиком мусора». Но происходит это не сразу, а тогда, когда система посчитает нужным это сделать. В большинстве случает это не имеет для программиста ни какого значения.

Пример. Дан массив из n действительных чисел. Вычесть из каждого элемента массива среднее значение массива. Распечатать полученный массив.

Возможный вариант решения:

using System;

namespace Prim_Mas1

{

   class Program

   {

      public static void Main(string[] args)

      {

         double []x = new double[5];

         int i, n = x.Length;

         Console.WriteLine("Задайте {0} вещественных чисел:", n);

         for(i = 0; i < n; i++)

         {

            Console.Write("x[{0}] = ", i);

            x[i] = double.Parse(Console.ReadLine());

         }

         double s = 0;

         for(i = 0; i < n; i++)

            s += x[i];

         s /= n; // это среднее значение

         for(i = 0; i < n; i++)

            x[i] -= s;

         Console.WriteLine("Массив после обработки:");

         foreach(double r in x)

            Console.WriteLine(r);

         Console.Write("Press any key to continue . . . ");

         Console.ReadKey(true);

      }

   }

}

Двумерные массивы (матрицы)

Двумерный массив имеет два измерения. Работа с матрицей, как и работа с одномерным массивом, начинается с создания ссылки на матрицу с последующим выделением памяти. Также возможна инициализация элементов матрицы. Пусть требуется создать матрицу действительных чисел A[2x3]. Рассмотрим варианты работы.

1)Создание ссылки на матрицу и выделение памяти:

double [,]a = new double[2, 3];

2)Создаём ссылку на матрицу, выделяем память и одновременно инициализируем элементы матрицы:

double [,]a = new double[2, 3]{{2,4,0},{1,6,4}};

Как видим, каждую строку берём в свой блок, в остальном всё делается так же, как и для одномерного массива.

То же самое можно записать по аналогии с одномерным массивом ещё проще:

double [,]a = new double[,]{{2,4,0},{1,6,4}};

Пример. Пронормировать матрицу действительных чисел A[2x3], т.е. каждый элемент матрицы поделить на максимальное по модулю число.

Возможный вариант решения:

using System;

namespace Prim_Matr1

{

   class Program

   {

      public static void Main(string[] args)

      {

         const int n = 2;

         const int m = 3;

         double [,]a = new double[n, m];

         int i, j;


         Console.WriteLine("Задайте матрицу A[{0}*{1}]:", n , m);

         for(i = 0; i < n; i++)

            for(j = 0; j < m; j++)

               a[i, j] = double.Parse(Console.ReadLine());


         double max = Math.Abs(a[0, 0]);

         for(i = 0; i < n; i++)

            for(j = 0; j < m; j++)

               if(Math.Abs(a[i, j]) > max)

                  max = Math.Abs(a[i, j]);

         Console.WriteLine("max = {0}", max);


         for(i = 0; i < n; i++)

            for(j = 0; j < m; j++)

               a[i, j] /= max;


         Console.WriteLine("Mатрица A[{0}*{1}] после нормирования:", n , m);

         for(i = 0; i < n; i++)

         {

            for(j = 0; j < m; j++)

               Console.Write(a[i,j]+"\t ");

            Console.WriteLine();

         }

         Console.Write("Press any key to continue . . . ");

         Console.ReadKey(true);

      }

   }

}

Многомерные массивы

При работе с многомерными массивами всё делается по аналогии. Единственно, надо учитывать количество измерений таких массивов.

Пример описания трёхмерного массива:

double [,,]V = new double[2, 3, 3];

Здесь выделяется память под массив, который можно представить состоящим из двух таблиц размером 3x3.

Пример инициализации трёхмерного массива:

double [,,]V = new double[2, 3, 3]

{

   {{2,4,0}, {1,6,4}, {5,3,3}},

   {{2,1,6}, {1,8,5}, {0,2,7}}

};

А ещё проще инициализировать так:

double [,,]V =

{

   {{2,4,0}, {1,6,4}, {5,3,3}},

   {{2,1,6}, {1,8,5}, {0,2,7}}

};

Дальнейшая работа с многомерными массивами ведётся как и с матрицами, только индексов больше и, как правило, возрастает вложенность циклов.

Стандартные методы и свойства для работы с массивами

Все массивы, как было сказано ранее, являются наследниками класса Array. Благодаря этому при работе с массивами имеется большое количество готовых методов и свойств. Рассмотрим некоторые из них. Во всех примерах x — одномерный массив, a — матрица.

Свойства

1)Length — возвращает количество элементов в массиве. Обычно используется в циклах, например:

for(i = 0; i < x.Length; i++)

   Console.WriteLine(x[i]);

2)Rank — возвращает размерность массива. Пример:

int r = a.Rank;

Console.WriteLine("Размерность=" + r);

Методы

1)Sort() — сортировка массива. Метод многократно перегружен. Примеры использования:

Array.Sort(x);

Array.Sort(x, 2, 3);

2)Reverse() — изменяем порядок следования элементов массива на обратный:

Array.Reverse(x);

А таким способом первые три элемента будут записаны в обратном порядке:

Array.Reverse(x, 0, 3);

3)BinarySearch() — поиск в упорядоченном массиве индекса элемента, равного заданному значению. Если поиск не увенчался успехом, то ответом будет отрицательное число. Пример:

int t =4;

int j = Array.BinarySearch(x, t);

5)LastIndexOf() — поиск последнего вхождения в массиве заданного значения, например, поиск положения числа 4 в массиве x. Если в массиве нет такого значения, то ответом будет отрицательное число.

int j = Array.LastIndexOf(x,4);

6)GetLength() — получение количества элементов по данной размерности. Размерности нумеруются с 0. Таким образом, для двумерного массива ввод массива действительных чисел с клавиатуры можно записать:

for(i = 0; i < a.GetLength(0); i++)

   for(j = 0; j < a.GetLength(1); j++)

      a[i, j] = double.Parse(Console.ReadLine());



Назад
На верх
Вперёд
Hosted by uCoz