Массив — это структура данных, содержащая несколько переменных, доступ к которым осуществляется по вычисляемым индексам. Содержащиеся в массиве переменные именуются элементами этого массива. Все они имеют одинаковый тип, который называется типом элементов массива. В C# массивы могут быть как одномерными, так и многомерными.
Одномерные массивы
Массивы в C# можно использовать почти так же, как и в других языках программирования, но у них есть одна особенность — они реализованы в виде объектов. Чтобы воспользоваться массивом в программе, необходимо сначала объявить переменную, которая может обращаться к массиву, а после — создать экземпляр массива, используя оператор new.
// Объявление массива
<тип>[] <имя>;
Пример:
int[] digits; // массив целых чисел
string[] strs; // массив строк
bool[] bools; // массив булевых значений
После объявления массива необходимо установить его размер с помощью ключевого слова new. Пример:
ints = new int[6];
Установить размер можно и при объявлении массива:
int[] ints = new int[6];
Инициализировать массив можно двумя способами: можно заполнить его поэлементно, а можно использовать фигурные скобки. При ручном заполнении помните, что нумерация начинается с 0.
ints[0] = 12;
ints[1] = 16;
ints[2] = 20;
ints[3] = 6;
ints[4] = 124;
Двумерные массивы
Многомерный массив содержит два или больше измерений, причем доступ к каждому элементу такого массива осуществляется с помощью определенной комбинации двух или более индексов.
Местоположение любого элемента в двумерном массиве обозначается двумя индексами. Такой массив можно представить в виде таблицы, на строки которой указывает один индекс, а на столбцы — другой.
int[] nums1 = new int[] { 0, 1, 2, 3, 4, 5 };
int[,] nums2 = { { 0, 1, 2 }, { 3, 4, 5 } };
Все возможные способы определения двухмерных массивов:
int[,] nums1;
int[,] nums2 = new int[2, 3];
int[,] nums3 = new int[2, 3] { { 0, 1, 2 }, { 3, 4, 5 } };
int[,] nums4 = new int[,] { { 0, 1, 2 }, { 3, 4, 5 } };
int[,] nums5 = new [,]{ { 0, 1, 2 }, { 3, 4, 5 } };
int[,] nums6 = { { 0, 1, 2 }, { 3, 4, 5 } };
Ступенчатые массивы
Ступенчатый массив — это массив массивов, в котором длина каждого массива может быть разной. Ступенчатый массивы объявляются с помощью ряда квадратных скобок, в которых указывается их размерность. Например, для объявления двумерного ступенчатого массива служит следующая общая форма:
тип [][] имя массива = new тип[размер] [];
Здесь размер обозначает число строк в массиве, а память для самих строк распределяется индивидуально, и поэтому длина строк может быть разной. Рассмотрим пример работы со ступенчатым массивом:
int i = 0;
// Объявляем ступенчатый массив
// В нем будет три массива длиной, соответственно,
// 3, 5 и 4 элемента
int[][] myArr = new int[3][];
myArr[0] = new int[3];
myArr[1] = new int[5];
myArr[2] = new int[4];
// Инициализируем ступенчатый массив
for (; i < 3; i++)
{
myArr[0][i] = i;
Console.Write("{0}\t", myArr[0][i]);
}
Console.WriteLine();
for (i = 0; i < 5; i++)
{
myArr[1][i] = i;
Console.Write("{0}\t", myArr[1][i]);
}
Console.WriteLine();
for (i = 0; i < 4; i++)
{
myArr[2][i] = i;
Console.Write("{0}\t", myArr[2][i]);
}
Класс Array. Сортировка массивов
Для создания массива можно еще использовать класс Array. Этот класс является абстрактным, поэтому создать массив с использованием какого-либо конструктора нельзя.
Но вместо применения синтаксиса C# для создания экземпляров массивов также возможно создавать их с помощью статического метода CreateInstance(). Это удобно, когда заранее неизвестен тип элементов массива.
// Создаем массив типа string, длиной 3
Array strs = Array.CreateInstance(typeof(string), 3);
// Инициализируем первые два поля массива
strs.SetValue("Brand", 0);
strs.SetValue("Model", 1);
// Считываем данные из массива
string s = (string)strs.GetValue(1);
С помощью разных вариантов метода Sort() можно отсортировать массив полностью или в заданных пределах либо отсортировать два массива, содержащих соответствующие пары "ключ-значение". Сортировка массива необходима, чтобы можно было осуществить эффективный поиск, используя разные варианты метода BinarySearch(). Пример сортировки массива:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
int[] myArr = { -5, 8, -12, 122, 34, -1, 0, 39};
Console.WriteLine("До сортировки: ");
foreach (int i in myArr)
Console.Write("\t{0}", i);
Array.Sort(myArr);
Console.WriteLine("\nПосле сортировки:");
foreach (int i in myArr)
Console.Write("\t{0}", i);
Console.ReadKey();
}
}
}
Копирование массивов
Поскольку массивы — это ссылочные типы, присваивание переменной типа массива другой переменной создает две переменных, ссылающихся на один и тот же массив. Для копирования массивов предусмотрена реализация массивами интерфейса ICloneable.
Метод Clone(), определенный в этом интерфейсе, создает неглубокую копию массива. Если элементы массива относятся к типу значений, то все они копируются, если массив содержит элементы ссылочных типов, то сами эти элементы не копируются, а копируются лишь ссылки на них.
Вместо метода Clone() можно также применять метод Array.Сору(), тоже создающий поверхностную копию. Но между Clone() и Сору() есть одно важное отличие: Clone() создает новый массив, а Сору() требует наличия существующего массива той же размерности с достаточным количеством элементов.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
string[] arr2 = new string[5];
// Создаем массив типа string, длиной 5
Array myArr = Array.CreateInstance(typeof(string),5);
// Инициализируем первые три поля массива
myArr.SetValue("Name",0);
myArr.SetValue("Age",1);
myArr.SetValue("Adress",2);
// Копируем массив с помощью метода Clone()
string[] arr1 = (string[])myArr.Clone();
foreach (string s in arr1)
Console.Write("\t"+s);
// Копируем с помощью метода Copy()
Console.WriteLine();
Array.Copy(myArr, arr2, myArr.Length);
foreach (string s in arr2)
Console.Write("\t"+s);
Console.ReadLine();
}
}
}
Перебор массивов. Цикл foreach
Цикл foreach предназначен для перебора элементов в контейнерах, в том числе в массивах. Формальное объявление цикла foreach:
foreach (тип_данных название_переменной in контейнер)
{
// действия
}
Например:
int[] numbers = new int[] { 1, 2, 3, 4, 5 };
foreach (int i in numbers)
{
Console.WriteLine(i);
}
Здесь в качестве контейнера выступает массив данных типа int. Поэтому мы объявляем переменную с типом int.
Массив - как параметр
Массив может выступать как параметр метода. Также метод может возвращать целый массив. Рассмотрим небольшой пример описания метода, принимающего массив в качестве параметра и возвращающего также массив:
static Array arrChange(Array Arr)
{
// делаем что-то с массивом Arr
return Arr;
}