Массивы — основа любого языка программирования. Знать, как они работают, необходимо любому уважающему себя разработчику. Ну а если вы только начинаете свой путь программиста — сначала нужно разобраться с определением и назначением этой базовой структуры данных. Сейчас мы последовательно обсудим все основные реализации массивов в C#.
Содержание
Массив — структура данных, содержащая ряд значений одинакового типа, расположенных последовательно, и обозначенная при помощи специального синтаксиса. Проще говоря, это набор однотипных значений хранящихся в последовательно расположенных ячейках памяти. Это полезная вещь избавила разработчиков от необходимости создавать тысячи переменных для каждого отдельно взятого значения. Вместо этого, с появлением такой структуры, мы просто делаем объявление переменной массива и добавляем туда поля одного типа данных, группируя их по определенному признаку. Уже оттуда можно получить доступ к конкретному элементу используя его порядковый номер (индекс).
Из основных преимущества массивов можно выделить: доступность значений хранящихся в различных ячейках памяти и более простое манипулирование данными (сортировка, перемещение и другие операции). Недостатки массива — ограничение его размера и условие однотипности (гомогенности) хранимых данных. Получить помощь при изучении этого языка программирования можно посетив курс наших друзей школы Hillel.
Далее поговорим о массивах на примере их реализации в языке C#.
C# предоставляет нам на выбор 3 различных типа массивов:
Для объявления 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 (data_type var_name in container)
{
// какой то код
}
Простой пример:
int[] digits = new int[] { 1, 2, 3, 4, 5 };
foreach (int i in digits)
{
Console.WriteLine(i);
}
Вместо контейнера у нас целочисленный массив, поэтому переменную мы объявляем с таким же типом. Оператор foreach, в данном случае, будет последовательно в цикле извлекать элементы нашего массива.
Это абстрактный базовый класс (что означает, что вы не можете создать экземпляр этого класса) предоставляет нам методы и свойства для работы с массивами в 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));
Кроме рассмотренных, данный класс содержит около двух десятков полезных статических методов и свойств.
тип данных [] имя массива.Lengthfor и foreach.System.Array, изобилующий полезными методами и свойствами, необходимыми в повседневной работе С-программиста.Тем кто хочет изучить язык более подробно, мы можем порекомендовать курс от друзей школы Hillel. Для тех людей, кому лучше изучать самостоятельно — добавляем несколько ссылок на актуальные обучающие видеоролики от опытных C#-разработчиков:
Что такое массивы / Одномерный массив
Инициализация массива
Как работать с массивом на самом деле
На фоне роста спроса на ликвидность в бычьем рынке 2025 года, криптозаймы снова выходят на…
Прокси (proxy), или прокси-сервер — это программа-посредник, которая обеспечивает соединение между пользователем и интернет-ресурсом. Принцип…
Согласитесь, было бы неплохо соединить в одно сайт и приложение для смартфона. Если вы еще…
Повсеместное распространение смартфонов привело к огромному спросу на мобильные игры и приложения. Миллиарды пользователей гаджетов…
В перечне популярных чат-ботов с искусственным интеллектом Google Bard (Gemini) еще не пользуется такой популярностью…
Скрипт (англ. — сценарий), — это небольшая программа, как правило, для веб-интерфейса, выполняющая определенную задачу.…