Массивы в C#: виды, примеры и работа с ними
Массивы — основа любого языка программирования. Знать, как они работают, необходимо любому уважающему себя разработчику. Ну а если вы только начинаете свой путь программиста — сначала нужно разобраться с определением и назначением этой базовой структуры данных. Сейчас мы последовательно обсудим все основные реализации массивов в C#.
Содержание
- Массивы в C# и работа с ними
- Какие бывают массивы в языке C#
- Объявляем и инициализируем массив в C#
- Неявная типизация массива
- Определение массива объектов
- Длина массива
- Доступ к элементам массива.
- Передача массива в метод
- Многомерные массивы
- Зубчатые массивы
- Перебор массивов (foreach)
- Класс System.Array
- Резюмируем:
Массивы в C# и работа с ними
Массив — структура данных, содержащая ряд значений одинакового типа, расположенных последовательно, и обозначенная при помощи специального синтаксиса. Проще говоря, это набор однотипных значений хранящихся в последовательно расположенных ячейках памяти. Это полезная вещь избавила разработчиков от необходимости создавать тысячи переменных для каждого отдельно взятого значения. Вместо этого, с появлением такой структуры, мы просто делаем объявление переменной массива и добавляем туда поля одного типа данных, группируя их по определенному признаку. Уже оттуда можно получить доступ к конкретному элементу используя его порядковый номер (индекс).
Из основных преимущества массивов можно выделить: доступность значений хранящихся в различных ячейках памяти и более простое манипулирование данными (сортировка, перемещение и другие операции). Недостатки массива — ограничение его размера и условие однотипности (гомогенности) хранимых данных. Получить помощь при изучении этого языка программирования можно посетив курс наших друзей школы Hillel.
Далее поговорим о массивах на примере их реализации в языке C#.
Какие бывают массивы в языке C#
C# предоставляет нам на выбор 3 различных типа массивов:
- Одномерный массив. Содержит только одну строку данных, поэтому к элементу, хранящемуся в массиве, довольно просто получить доступ с помощью одного числового индекса, ( 0, 1, 2 и т. д.)
- Многомерный массив. Содержит более одной строки с данными, поэтому его индекс будет состоять из пары чисел, одно из которых идентифицирует строку, а другое — столбец. Такой массив часто называют прямоугольным, так как он принимает форму прямоугольника, если представить его схематично.
- Зубчатый массив. Это массив, состоящий из подмассивов(причем эти подмассивы могут быть любого размера).
Объявляем и инициализируем массив в C#
Для объявления C#-массива используется эта нехитрая конструкция:
тип данных [] имя массива ;
Объявление C#-массива / Источник: coderlessons.com
Например :
int [] integerArray; // числовой массив string [] stringArray; // строковый массив bool [] booleanArray; // логический массив
Как и во многих других языках программирования, в этом примере массив объявлен, но не создан. Для того чтобы создать экземпляр массива используется ключевое слово new
.
Например:
int32 [] values; // объявленный массив values пока не создан values = new int32[3]; // сейчас мы его создали, при этом определили, что он будет состоять из 3 целых чисел, но пока не заполнили значениями values[0]=1; // значение первого элемента этого массива теперь равно единице. В квадратных скобках 0, ведь считать элементы в массиве надо начинать именно с него.
Следуюший шаг — инициализируем наш массив.
Инициализация — это процедура присваивания значений свободным ячейкам массива. Информация может присваиваться поэлементно, как в последнем действии предыдущего примера:
values[0]=1; values[1]=2; values[2]=3;
Инициализация массива / Источник: coderlessons.com
Теперь попытаемся вывести в консоль значения элементов массива:
Значения элементов / Источник: coderlessons.com
Этот код распечатает следующие значения:
1 2 3
Но есть еще и другой способ инициализации. Вместо использования ключевого слова new
, необходимые значения нашего массива можно перечислить в фигурных скобках. Например:
int32[] values = { 1, 2, 3};
В этом случае компилятор сначало посчитает количество переменных, потом определит тип, выделит необходимое количество ячеек в области оперативной памяти и проинициализирует их необходимыми значениями. При объявлении массива через new
, все элементы инициализируются автоматически:
- нулями — для цельночислового типа;
false
— для логического;null
— для ссылок.
Неявная типизация массива
Как и при работе с обыкновенными переменными, при объявлении массива существует возможность типизировать его неявно, поставив перед ним ключевое слово var
. В такой ситуации компилятору C# придется определять типы элементов по их инициализируемым значениям. Вот небольшой пример неявной типизации массива:
var capitals = new[] { “Moscow”, “Washington”, “Antananarivo” }; // Массиву будет автоматически присвоен строковый тип var integers= new[] { 3, 12, 43, 24, 7 }; // Массиву будет присвоен целочисленный тип var mixer = new[] { 6, 24.3951d, false, “twelve”}; // А в этом случае, компилятор не определится с типом и выведет ошибку (т.к. в одном массиве присутствуют значения явно разных типов).
Определение массива объектов
Система типов используемая C# построена на системе наследования, в корне которой лежит класс System.Object
, являющийся базой для всех типов данных. Такой подход помогает создавать массивы object
, в ячейках которых можно хранить любые данные. Массив объектов как раз и используется для хранения разнотипных элементов. В C# ссылка на объект может указывать на любой экземпляр производного типа. Однако у такой структуры есть свои недостатки. Такая методика несколько усложняет код и увеличивает время выполнения программы.
Пример:
using System; class GFG { static public void Main() { object[] arr = new object[6];// Создаем и инициализируем object array arr[0] = 1.859; arr[1] = 7; arr[2] = 'g'; arr[3] = "hello"; arr[4] = null;// это не отобразиться на выходе arr[5] = new object();// выведет System.Object foreach(var item in arr) { Console.WriteLine(item);// выводим элементы в консоль } } }
Результат:
1,859 7 g hello System.Object
Длина массива
В С# существует параметр для измерения размера массива — это свойство Length
. Оно возвращает нам количество, находящихся в массиве элементов, которое, после того как массив создан, изменить нельзя. Для доступа к этому параметру применяем следующий синтаксис:
arrayVariable.Length;
В этом примере рассматриваемое свойство используется для ссылки на последний элемент в массиве:
using System; class MainClass{ static void Main(){ int[] myArr = new int[] { 1, 7, 6, 12, 18 }; Console.WriteLine(myArr [myArr.Length-1]); } }
Выведет: 18
Доступ к элементам массива.
Как мы уже упоминали ранее, для доступа к элементу массива нужно воспользоваться его порядковым номером (индексом). Например:
int[] digits = new int[4]; digits[0] = 1; digits[1] = 3; digits[2] = 4; digits[3] = 5; Console.WriteLine(digits[3]); // 5
Не забываем, что нумерация элементов массива начинается с нуля, поэтому индекс 1-ого элемента будет 0, а четвертого — 3 ( digits[3]
). Мы изначально задали, что наш массив состоит из 4 элементов, поэтому, если обратиться, например, к шестому элементу digits[5] = 5
— получим в результате исключение IndexOutOfRangeException
.
Передача массива в метод
Стандартная форма, при которой одномерный массив передается в метод выглядит так:
public return_type MethodName(type[] parameterName) { // ... }
Здесь:
public
– модификатор доступа;return_type
– тип, который вернул нам метод;MethodName
– имя метода;type
– тип массива, переданного в метод;parameterName
– название массива, являющегося одним из параметров нашего метода.
В следующем примере мы передаем массив в метод PrintArray
.
int[] theArray = { 1, 3, 5, 7, 9 }; PrintArray(theArray); Реализация метода печати. void PrintArray(int[] arr) { // какой-то код }
Теперь все это можно соединить вместе, как показано в следующем примере:
PrintArray(new int[] { 1, 3, 5, 7, 9 });
Многомерные массивы
В многомерном массиве каждый элемент также является массивом. Например:
int[ , ] i = { { 1, 2 ,3}, { 3, 4, 5 } };
Здесь i
— это многомерный массив, состоящий из двух элементов: {1, 2, 3}
и {3, 4, 5}
. Каждый элемент такого массива является массивом размером в 3 элемента. Чаще всего C#-разработчики применяют в своей работе двумерные массивы, их мы и рассмотрим более подробно.
Двумерный массив можно представить в виде таблицы с определенным количеством строк и столбцов.
Подмассивы {1, 2, 3}
и {3, 4, 5}
являются элементами нашего двумерного массива.
Вот как он объявляется в C#:
int[ , ] i= new int [2, 3];
Здесь i
— это двумерный массив состоящий из двух элементов, а каждый элемент представляет собой вложенный массив из 3 элементов. Если посчитать, всего в таком массиве можно хранить 6 элементов.
Примечание: Единственная запятая в этом коде [,]
означает, что массив является двумерным.
Также как и с одномерным массивом, в C# мы можем инициализировать двумерный массив во время объявления. Например:
int[ , ] i = { { 1, 2 ,3}, { 3, 4, 5 } };
Еще мы можем указать количество строк и столбцов во время инициализации. Например:
int [ , ] i = new int[2, 3]{ {1, 2, 3}, {3, 4, 5} };
Для доступа к элементам рассматриваемого нами массива — используем индексы. Например:
int[ , ] i = { { 1, 2 ,3}, { 3, 4, 5 } }; // доступ к первому элементу в строке i[0, 0]; // вернет 1 // доступ ко второму элементу в строке i[1, 2]; // вернет 5 // доступ к третьему элементу в строке i[0, 2]; // вернет 3
Пример 2D-массива:
using System; namespace MultiArray { class Prog { static void Main(string[] args) { //инициализируем двумерный массив int[ , ] digits = {{2, 3}, {4, 5}}; // доступ к первому элементу в первой строке Console.WriteLine("Element at index [0, 0] : "+digits[0, 0]); // доступ к первому элементу в второй строке Console.WriteLine("Element at index [1, 0] : "+digits[1, 0]); } } }
Выведет:
Element at index [0, 0] : 2 Element at index [1, 0] : 4
В приведенном выше примере мы создали 2D-массив с элементами {2, 3}
и {4, 5}
.
и использовали номера индексов для доступа к элементам:
digits[0, 0]
— доступ к первому элементу из первой строки ( 2 )digits[1, 0]
— доступ к первому элементу из второго ряда ( 4 )
Зубчатые массивы
Массив массивов (он же «зубчатый») отличается от многомерного тем, что в его состав могут входить подмассивы различной длины. Записывается он, при помощи двух пар квадратных скобок, при этом его длина обозначается только в в первой паре скобок. Например:
int[][] digits = new int[3][]; digits[0] = new int[2] { 1, 2 }; // выделяется место первому подмассиву digits[1] = new int[3] { 1, 2, 3 }; // выделяется место второму подмассиву digits[2] = new int[5] { 1, 2, 3, 4, 5 }; // выделяется место третьему подмассиву
Здесь у нас массив digits
содержащий в себе три подмассива. Причем размерность каждого из них не совпадает, схематично образуя своеобразные зубья, за счет разной длины.
В качестве подмассивов в нем можно использовать даже многомерные массивы:
int[][,] digits = new int[3][,] { new int[,] { {1,2}, {3,4} }, new int[,] { {1,2}, {3,6} }, new int[,] { {1,2}, {3,5}, {8, 13} } };
На следующей картинке изображены примеры существующих в C# массивов:
Примеры существующих в C# массивов / Источник: metanit.com
Перебор массивов (foreach)
При помощи цикла foreach
мы можем перебирать элементы в любом контейнере, в том числе и в массиве. Синтаксис для его объявления такой:
foreach (data_type var_name in container) { // какой то код }
Простой пример:
int[] digits = new int[] { 1, 2, 3, 4, 5 }; foreach (int i in digits) { Console.WriteLine(i); }
Вместо контейнера у нас целочисленный массив, поэтому переменную мы объявляем с таким же типом. Оператор foreach
, в данном случае, будет последовательно в цикле извлекать элементы нашего массива.
Класс System.Array
Это абстрактный базовый класс (что означает, что вы не можете создать экземпляр этого класса) предоставляет нам методы и свойства для работы с массивами в C#. Разберем небольшой пример, где реализуем метод данного класса CreateInstance
, создающий экземпляр массива. В нем, первым параметром будет тип, а вторым — измерение (т.е размерность массива: одномерный, двумерный и т.д.). А после создания нашего массива применим метод GetValue
для добавления в него элементов.
Пример:
System.Array myArray; myArray = System.Array.CreateInstance (GetType (string), 3); myArray.SetValue ("one", 0); myArray.SetValue ("two", 1); myArray.SetValue («three», 2); myArray = System.Array.CreateInstance (GetType (string), 3, «one», «two», «three»); sValue = System.Convert.ToString (myArray.GetValue (2));
Кроме рассмотренных, данный класс содержит около двух десятков полезных статических методов и свойств.
Резюмируем:
- Массивы нужны для структурирования и хранения информации
- Для объявления C#-массива необходимо указать его тип, квадратные скобки( знак массива) и как-то его назвать :
тип данных [] имя массива
. - Инициализировать массив можно добавляя значение каждому элементу последовательно или перечислить значения в фигурных скобках, во время объявления, заставляя компилятор проставить необходимые сведения самому.
- В C# существует возможность реализовать массив объектов для хранения разнотипных элементов.
- Для определения длины массива используем свойство
Length
- Многомерные массивы служат для хранения других массивов(в качестве элементов) с одинаковой длиной. Если длина хранящихся подмассивов неодинаковая — используем зубчатый массив.
- Для перебора массивов используем циклы
for
иforeach
. - Для удобства работы с рассматриваемыми структурами данных используем класс
System.Array
, изобилующий полезными методами и свойствами, необходимыми в повседневной работе С-программиста.
Тем кто хочет изучить язык более подробно, мы можем порекомендовать курс от друзей школы Hillel. Для тех людей, кому лучше изучать самостоятельно — добавляем несколько ссылок на актуальные обучающие видеоролики от опытных C#-разработчиков:
Что такое массивы / Одномерный массив
Инициализация массива
Как работать с массивом на самом деле
Сообщить об опечатке
Текст, который будет отправлен нашим редакторам: