Массив — это совокупность данных одного типа, имеющих одно общее имя. Доступ к элементам массива осуществляется путём указания имени массива и номера элемента.
Особенностью массивов в 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);
начиная с i-го элемента, упорядывачиваем k элементов массива (у нас: сортируем 3 элемента, начиная с 2-го):
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);
4)IndexOf() — поиск первого вхождения в массиве заданного значения, например, поиск положения числа 4 в массиве x. Если в массиве нет такого значения, то ответом будет отрицательное число.
int j = Array.IndexOf(x,4);
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());
|
|
|